Web push notifications for Drupal
Drupal gives you full control of the web root and a proper asset system, so web push fits neatly: a file in the docroot and a theme library. Here’s the Drupal-native way, plus quicker options.
- Put sw.js in the docroot — web/ in Composer-based projects — so /sw.js opens.
- Add the script as an external library in your theme’s libraries.yml with async and data-site attributes.
- No custom theme? A module such as Asset Injector can add it site-wide.
- Drupal’s page cache and JS aggregation don’t affect an external async script.
1. sw.js in the docroot
Every web push service has the same requirement: browsers only deliver push to a service worker served from your domain, and Pusharoo registers its worker with scope /, so https://yoursite.com/sw.js must open as JavaScript. Platforms where you control the web root make this a one-minute job; hosted platforms that don’t let you place a root file need a workaround or won’t work.
In projects created with drupal/recommended-project, the public docroot is web/, not the repository root. Commit web/sw.js (and make sure your deploy doesn’t delete unknown files there). Drupal’s .htaccess serves existing files directly; with nginx, a standard Drupal config also serves static files before passing to PHP.
2. Add the snippet as a theme library
# mytheme.libraries.yml
pusharoo:
header: true
js:
https://pusharoo.com/sdk/pusharoo.js:
type: external
attributes:
async: true
data-site: pk_your_site_key# mytheme.info.yml — load it on every page
libraries:
- mytheme/pusharooClear caches (drush cr) and view source: the script tag should appear in the head with both attributes. Using a library keeps the snippet in version control and out of the database.
Quicker options
- Asset Injector (contributed module): add a JS injector, or an HTML snippet where supported, for all pages.
- html.html.twig override in your theme: paste the snippet before
</head>. - Google Tag Manager module: add the snippet as a Custom HTML tag (you still need
/sw.js).
Caching notes
Drupal’s Internal Page Cache and Dynamic Page Cache store HTML; the script tag is part of that HTML, so cached pages still load it. Aggregation only combines local files — external libraries are left alone. Exclude /sw.js from Varnish or CDN caching so worker updates reach visitors quickly.
3. Notify readers about new content
Drupal Views can publish an RSS feed of new nodes (the default /rss.xml lists front-page content). Add it in Pusharoo under Integrations → Add a feed to send new posts automatically or as drafts for review. For editorial control, many teams prefer drafts: an editor checks the title, then sends.
Sending from Drupal code
For transactional notices — a ticket updated, a form approved — call Pusharoo’s REST API from a custom module with Drupal’s HTTP client (\Drupal::httpClient()), using POST /api/v1/notify with the subscriber IDs you saved from the subscribe webhook. Keep the API key in settings.php or an environment variable, never in config exported to Git.
Roles and who can send
Keep sending outside Drupal’s content roles: marketers compose in the Pusharoo dashboard, while Drupal only renders the snippet and optionally calls the REST API for transactional messages. That way no Drupal permission change can accidentally expose a “send to everyone” button.
Test checklist
- Open
https://yoursite.com/sw.js— you should see JavaScript, not a 404 or your theme’s error page. - Open the site in Chrome, wait for the prompt and allow twice.
- Check that the subscriber count rises in the dashboard, then send yourself a test.
- Repeat on Android, and on iPhone after adding the site to the Home Screen (testing guide).
Questions
Is there a Drupal module for web push?
There are contributed modules that implement push themselves (you manage VAPID keys and sending). With Pusharoo you only add a file and a library; sending, segments and cleanup are handled for you.
Where does sw.js go in a Composer project?
In the public docroot, usually web/, so it opens at https://yoursite.com/sw.js.
Does this work on multisite?
Yes. Add each domain as a website in Pusharoo and use per-site keys (for example via a theme setting or per-site library).
Can I add the snippet with Google Tag Manager on Drupal?
Yes, via the GTM module and a Custom HTML tag; sw.js must still be in the docroot.
Does it work on Acquia or Pantheon?
Yes, as long as you can commit sw.js to the docroot and it’s served as JavaScript without long caching.
Keep reading
Web push notifications for Joomla
Root sw.js, the snippet in a Cassiopeia child template, why Custom modules strip scripts, and caching.
Web push for WordPress and WooCommerce
Upload sw.js, paste one line, exclude it from caching. Works with WooCommerce too.
Push notifications for publishers and blogs
What to push, breaking news vs. digests, frequency, segments and growing loyal returning readers.
Web push notifications in PHP
Install with Composer, create VAPID keys, store subscriptions, queue and flush, remove expired endpoints.
More in Platforms: Web push on Shopify: what works, honestly · WooCommerce push notifications: setup and playbook · Magento 2 push notifications · Web push on Wix, Squarespace and Webflow · Web push notifications on BigCommerce · Web push notifications for PrestaShop · Web push notifications for Ghost blogs · All guides
Free for life. No limits.
Unlimited subscribers, campaigns and automations. No badges. About five minutes to install.