JavaScript PushManager subscribe() Method

Beginner
⏱️ 12 min read
📚 Updated: Jul 2026
🎯 5 Examples
🚀 5 Try-it labs
Baseline Widely available
Instance method

What You’ll Learn

The subscribe() method on PushManager creates a push subscription and returns a PushSubscription with endpoint and encryption keys. Learn the MDN serviceWorker.ready pattern, userVisibleOnly and VAPID applicationServerKey, user-gesture best practices, and syncing to your server—with five examples and try-it labs.

01

Kind

Instance method

02

Returns

Promise

03

Value

PushSubscription

04

Options

VAPID key

05

Gesture

button click

06

Status

Baseline Mar 2023

Introduction

Web push lets your server send messages to users even when your PWA is closed. To enable that, the browser needs a PushSubscription—an endpoint URL plus encryption keys your server uses to deliver encrypted payloads.

pushManager.subscribe() requests that subscription from the push service. MDN marks it Baseline Widely available (since March 2023). It may prompt the user for notification permission and should be called after navigator.serviceWorker.ready, ideally from a button click.

💡
subscribe() vs getSubscription()

Call getSubscription() on page load to check for an existing subscription. Call subscribe() when the user clicks “Enable Push”—it creates a subscription if none exists.

Understanding subscribe()

An instance method on PushManager that subscribes to a push service and returns subscription details.

  • Parameters — optional options object.
  • userVisibleOnly — must be true in Chrome and Edge.
  • applicationServerKey — VAPID public key (Uint8Array or base64).
  • ReturnsPromise<PushSubscription>.
  • Creates or reuses — new subscription if none exists for this SW.
  • User gesture — call from button click per MDN best practice.
  • Secure context — HTTPS or localhost required.
  • Available in Web Workers per MDN.

📝 Syntax

JavaScript
pushManager.subscribe(options)

Return value

A Promise resolving to a PushSubscription object with endpoint and key material for your push server.

MDN pattern

JavaScript
const registration = await navigator.serviceWorker.ready;

const subscription = await registration.pushManager.subscribe({
  userVisibleOnly: true,
  applicationServerKey: urlBase64ToUint8Array(VAPID_PUBLIC_KEY),
});

console.log(subscription.endpoint);

⚡ Quick Reference

GoalCode / note
Subscribeawait pushManager.subscribe({ userVisibleOnly: true, applicationServerKey })
After SW readyawait navigator.serviceWorker.ready
User gestureCall from button click handler
Check firstgetSubscription() to avoid duplicate prompts
Send to serversubscription.toJSON() or fetch()
MDN statusBaseline Widely available

🔍 At a Glance

Four facts to remember about subscribe().

Async
Promise

PushSubscription

VAPID
app key

Required in Chrome

Gesture
click

User action

Status
Baseline

Since Mar 2023

Examples Gallery

Examples follow MDN subscribe() patterns. Use View Output or Try It Yourself.

📚 Getting Started

Subscribe after serviceWorker.ready.

Example 1 — MDN subscribe() Pattern

Subscribe with userVisibleOnly and VAPID key.

JavaScript
navigator.serviceWorker.ready.then((registration) => {
  const options = {
    userVisibleOnly: true,
    applicationServerKey,
  };

  registration.pushManager.subscribe(options).then(
    (pushSubscription) => {
      console.log(pushSubscription.endpoint);
      // Send pushSubscription to your application server
    },
    (error) => {
      console.error(error);
    }
  );
});
Try It Yourself

How It Works

Always wait for serviceWorker.ready before calling pushManager.subscribe().

Example 2 — Subscribe on Button Click (MDN)

Call subscribe() in response to a user gesture.

JavaScript
btn.addEventListener("click", async () => {
  const registration = await navigator.serviceWorker.ready;

  try {
    const subscription = await registration.pushManager.subscribe({
      userVisibleOnly: true,
      applicationServerKey: vapidKey,
    });
    console.log("Subscribed:", subscription.endpoint);
  } catch (error) {
    console.error("Subscribe failed:", error);
  }
});
Try It Yourself

How It Works

MDN: browsers disallow notification prompts not triggered by user interaction (Firefox 72+).

📈 Practical Patterns

VAPID keys, checks, and server sync.

Example 3 — VAPID applicationServerKey

Convert a URL-safe base64 VAPID public key to Uint8Array.

JavaScript
function urlBase64ToUint8Array(base64String) {
  const padding = "=".repeat((4 - (base64String.length % 4)) % 4);
  const base64 = (base64String + padding).replace(/-/g, "+").replace(/_/g, "/");
  const raw = atob(base64);
  return Uint8Array.from([...raw].map((c) => c.charCodeAt(0)));
}

const VAPID_PUBLIC_KEY = "BEl62iUYgUivxIkv69yViEuiBIa-Ib9-SkvMeAtA3LFgDzkrxZJjSgSnfckjBJuBkr3qBUYIHBQFLXYp5Nksh8U";

const subscription = await pushManager.subscribe({
  userVisibleOnly: true,
  applicationServerKey: urlBase64ToUint8Array(VAPID_PUBLIC_KEY),
});
Try It Yourself

How It Works

Chrome and Edge require applicationServerKey for Web Push with VAPID.

Example 4 — Check getSubscription() First

Avoid duplicate subscriptions on repeat clicks.

JavaScript
const registration = await navigator.serviceWorker.ready;
const pm = registration.pushManager;

let subscription = await pm.getSubscription();

if (!subscription) {
  subscription = await pm.subscribe({
    userVisibleOnly: true,
    applicationServerKey: vapidKey,
  });
}

console.log("Active subscription:", subscription.endpoint);
Try It Yourself

How It Works

subscribe() returns the existing subscription if one is already active.

Example 5 — Send Subscription to Your Server

POST the PushSubscription JSON after subscribing.

JavaScript
const subscription = await registration.pushManager.subscribe({
  userVisibleOnly: true,
  applicationServerKey: vapidKey,
});

await fetch("/api/push-subscription", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify(subscription),
});

console.log("Subscription synced to server");
Try It Yourself

How It Works

Your server stores endpoint and keys to send encrypted push messages later.

🚀 Common Use Cases

  • Enabling push notifications when the user clicks “Subscribe”.
  • Creating a PushSubscription for a new PWA install.
  • Re-subscribing after the user clears site data.
  • Pairing with permissionState() to gate the subscribe button.
  • Replacing deprecated register() in legacy migrations.
  • Syncing subscription JSON to your backend for server-side push.

🔧 How It Works

1

User clicks

Subscribe triggered by button gesture.

Gesture
2

SW ready

registration.pushManager.subscribe(options).

Subscribe
3

Permission

Browser may prompt; user grants or denies.

Prompt
4

PushSubscription

Endpoint + keys returned; sync to your server.

📝 Notes

Universal Browser Support

The PushManager.subscribe() method is Baseline Widely available on MDN (since March 2023). Requires a secure context and VAPID key in Chromium browsers. Logos use the shared browser-image-sprite.png sprite from this project.

Baseline · Widely available

PushManager.subscribe()

Create PushSubscription with endpoint and keys in modern browsers.

Universal Widely available
Google Chrome Full support · VAPID required
Full support
Mozilla Firefox Full support · User gesture required
Full support
Apple Safari Full support · macOS & iOS
Full support
Microsoft Edge Full support · Chromium
Full support
Opera Full support · Modern versions
Full support
Internet Explorer No Push API / service workers
Not supported
subscribe() Excellent

Bottom line: Call after serviceWorker.ready from a user gesture with userVisibleOnly: true and VAPID key.

Conclusion

pushManager.subscribe() is the modern way to create a push subscription. Call it after serviceWorker.ready from a user gesture, pass userVisibleOnly: true and your VAPID key, then send the PushSubscription to your server.

Continue with getSubscription(), permissionState(), PushEvent.data, or the JavaScript hub.

💡 Best Practices

✅ Do

  • Call subscribe() from a button click
  • Set userVisibleOnly: true
  • Include VAPID applicationServerKey
  • Check getSubscription() before subscribing
  • POST subscription JSON to your server

❌ Don’t

  • Call subscribe() automatically on page load
  • Skip the service worker ready step
  • Use deprecated register() in new code
  • Expect it to work outside a secure context
  • Forget to handle permission denied errors

Key Takeaways

Knowledge Unlocked

Five things to remember about subscribe()

Create push subscriptions the modern way.

5
Core concepts
🔄02

Promise

async

Returns
🔑03

VAPID

app key

Options
👆04

Gesture

click

UX
🎯05

Baseline

since Mar 2023

Status

❓ Frequently Asked Questions

It subscribes to a push service and returns a Promise that resolves to a PushSubscription object with endpoint URL and encryption keys. A new subscription is created if none exists for the current service worker.
No. MDN marks PushManager.subscribe() as Baseline Widely available (since March 2023). It is not Deprecated, Experimental, or Non-standard.
An optional object with userVisibleOnly (boolean, required true in Chrome/Edge) and applicationServerKey (VAPID public key as Uint8Array or base64 string).
After navigator.serviceWorker.ready, typically in response to a user gesture (button click). Browsers may block subscribe prompts not triggered by user interaction.
subscribe() creates or returns a push subscription and may prompt the user. getSubscription() only reads the current subscription without creating one.
On registration.pushManager after navigator.serviceWorker.ready, in a secure context (HTTPS or localhost). Also available in Web Workers per MDN.
Did you know?

MDN notes that subscribe() returns an existing subscription if the service worker already has one—but checking with getSubscription() first still helps you control UI and avoid unnecessary permission prompts.

Check existing subscription

Learn getSubscription()—call before subscribe on page load.

getSubscription() →

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

5 people found this page helpful