webdevpuneet.com

Push Notification Subscription Toggle — Free Notification API Demo

Push Notification Subscription Toggle · Buttons · Plain HTML, CSS & JS · Live preview

CategoryButtons

Copy & paste

Source Code

<section class="pst-wrap">
  <span class="pst-tag">Notification.requestPermission</span>
  <h1>Push notifications</h1>
  <p id="pstStatus">Toggling this requests real browser notification permission and fires a real local test notification — it does not subscribe you to a push server.</p>

  <div class="pst-toggle-row">
    <div class="pst-toggle-text">
      <strong>Enable notifications</strong>
      <span id="pstPermLabel">Checking permission…</span>
    </div>
    <button class="pst-switch" id="pstSwitch" role="switch" aria-checked="false">
      <span class="pst-switch-thumb"></span>
    </button>
  </div>

  <button class="pst-test-btn" id="pstTest" disabled>Send a local test notification</button>

  <div class="pst-distinction">
    <div class="pst-distinction-item">
      <span class="pst-dot granted" id="pstDotPerm"></span>
      <div><strong>Permission granted</strong><p>The browser allows this origin to show notifications. That's all a toggle like this can honestly demonstrate.</p></div>
    </div>
    <div class="pst-distinction-item">
      <span class="pst-dot"></span>
      <div><strong>Actually subscribed to push</strong><p>Requires a service worker registration plus a real push server and VAPID key pair — not something a sandboxed snippet preview can provide.</p></div>
    </div>
  </div>

  <p class="pst-note" id="pstNote"></p>
</section>

Extend with AI

Take This Snippet Further With AI

The AI prompt for this one is for Patreon supporters ($3 a month, 7 days free), along with a site with no ads. Supporters enter the passcode once and it is remembered in this browser.

· Become a supporter

What's included

Features

Real requestPermission() calls
Genuine browser permission prompt, not simulated.
Genuine local test notification
new Notification() fires for real while the page is open.
Granted-vs-subscribed distinction
Explicit UI panel separating the two concepts.
Honest revoke limitation
States plainly that pages can't un-grant permission.
Denied-state messaging
Explains why re-prompting after denial is impossible.
Push infrastructure explained
Comments outline the real service-worker/VAPID path.
Graceful unsupported path
Disables the toggle cleanly when Notification is absent.
No dependencies
Pure vanilla JS against native APIs.

About this UI Snippet

Push Notification Subscription Toggle — Real Permission, Honestly Scoped

Screenshot of the Push Notification Subscription Toggle snippet rendered live

This snippet requests genuine browser notification permission and fires a real local notification — but it's deliberately upfront that neither of those is the same thing as a working push subscription, which needs infrastructure a client-side snippet can't provide.

Two different things people conflate

"Notifications are on" in a browser's UI can mean either of two very different states: the origin has *permission* to show notifications (a synchronous, client-only grant), or the browser has an active *push subscription* delivering messages from a server even when no tab is open. This snippet's toggle only ever produces the first — Notification.requestPermission() — and says so explicitly next to a second, grayed-out item explaining what subscribing would additionally require.

Permission can't be revoked from the page

Once Notification.permission is 'granted', no page-side API can turn it back off — that's a deliberate browser security boundary, since a site shouldn't be able to silently disable a user-controlled setting. The toggle's click handler checks for this and explains that only the user, via browser site settings, can revoke it, rather than pretending the switch has that power.

A local notification is not push

The "Send a local test notification" button calls new Notification(...) directly from the page — genuinely real, but fundamentally different from push: it can only fire while this page is open, whereas a real push message arrives through a service worker's push event, dispatched by the browser even with every tab of the site closed, triggered by your server sending an authenticated request to a push service using the subscription's endpoint and a VAPID key pair.

Why full push can't run in this sandbox

A complete implementation needs a registered service worker (navigator.serviceWorker.register), a pushManager.subscribe({ applicationServerKey }) call producing an endpoint URL, and a server that stores that endpoint and holds VAPID keys to actually send messages. None of that fits in a self-contained preview snippet, so the JS comments show exactly where that real call would go rather than pretending to run it.

Pair this with notification permission prompt for a simpler single-purpose version, or badging API demo for a related unread-count capability.

Step by step

How to Use

  1. 1
    Paste HTML, CSS, and JSA permission toggle and test-notification button render.
  2. 2
    Click the toggleA real Notification.requestPermission() prompt appears.
  3. 3
    Allow itThe switch turns on and the test button becomes enabled.
  4. 4
    Click "Send a local test notification"A genuine new Notification() fires from the page.
  5. 5
    Try toggling againThe copy explains permission can't be revoked from the page.
  6. 6
    Read the distinction panelClarifies granted permission versus an actual push subscription.

Real-world uses

Common Use Cases

Notification settings pages
Add a notification-preferences toggle to an account area, with copy that separates permission granted from actually subscribed to push.
Onboarding permission asks
Ask for notification permission at the right moment, with a real Notification.requestPermission() call and a genuine local test notification.
Push versus permission education
Explain that permission and a working push subscription are different things, since the latter also needs a service worker and server infrastructure.
PWA feature checklists
Show what is needed before real push works, using the app badge demo as a companion capability.
Support and test tools
Illustrate why a user's notifications are not appearing, or use as a quick local-fire button during development, stating plainly that pages cannot revoke permission.
Related: WhatsApp Floating Button
See the WhatsApp Floating Button for a related buttons pattern worth pairing with this one.

Got questions?

Frequently Asked Questions

No — it only requests and grants browser notification permission via Notification.requestPermission(). An actual push subscription additionally requires a registered service worker, a call to pushManager.subscribe() with a VAPID application server key, and a real server that stores the resulting subscription endpoint and sends authenticated push messages to it. This snippet is upfront that it demonstrates only the permission half.

Browsers deliberately give web pages no API to revoke a granted Notification permission — only the user can do that, through the browser's own site settings or permissions UI. This is a security boundary preventing a site from silently disabling a setting the user explicitly controls. The toggle's handler detects the already-granted state and explains this rather than attempting (and failing) to revoke it.

new Notification(...) is called directly from a page's own JavaScript and can only fire while that page (or a service worker it controls) is running. A real push notification arrives through a service worker's push event, dispatched by the browser even when every tab of the site is closed, triggered by a message your server sent to a push service using the subscription's endpoint and VAPID keys — infrastructure this local test button doesn't use.

A working push subscription needs a service worker that can actually register and control the page's scope, plus a real backend server holding VAPID keys and able to send authenticated push messages to a browser's push service. A self-contained preview snippet has neither a persistent origin for service worker registration nor a server, so this demo shows exactly where those real calls (pushManager.subscribe, server-side send) would go as comments rather than executing them.

Keep the permission-check and requestPermission() logic as-is in a handler, and drive the switch's visual state from Notification.permission read on mount (there's no change event for permission, so re-check it after any requestPermission() call resolves). For real push, add service worker registration and pushManager.subscribe() in a separate effect, gated behind your own backend endpoint for storing the subscription.