Web push for a WordPress site, powered by Pushix. The plugin adds the web SDK to every page, serves the service worker file for you, and can send a notification when you publish a post.
Needs WordPress 6.0+, PHP 7.4+, and HTTPS on both your site and the Pushix server. Tested with WordPress 6.2 and 6.5.
Install
- Download the plugin: your Pushix dashboard → Setup guide → Website → WordPress → Download the WordPress plugin, or
https://pushix.in/sdk/pushix-wordpress.zip. (It is thesdks/wordpress/pushixfolder, zipped.) - In WordPress open Plugins → Add New Plugin → Upload Plugin, choose
pushix-wordpress.zipand click Install Now, then Activate. (Or upload thepushixfolder towp-content/plugins/and activate it.) - In the Pushix dashboard open App settings → Channels → Website — web push, click Turn on web push and set the website address to your WordPress address.
- In WordPress open Settings → Pushix, enter the server URL and App ID, and click Save Changes.
- Click Check connection. It should say "The app was found and web push is on."
Open your site in a private window: the prompt you chose in the dashboard appears, and anyone who allows notifications shows up in Pushix under Subscribers with platform Web.
Settings
Settings → Pushix (administrators only):
| Setting | |
|---|---|
| Pushix server URL | e.g. https://pushix.in. Pasting the dashboard address works too; /dashboard/… is removed. |
| App ID | From App settings in the dashboard. |
| REST API key | Optional. Only needed to send notifications when you publish. Saved in the database, never shown again or printed into any page. Leave the field empty to keep the saved key; tick Remove the saved key to delete it. |
| Send automatically | Ticks "Send a push notification" in the editor by default. Editors can untick it for a single post. |
| Post types | Which post types get the "Push notification" box and can send. Default: Posts. |
| Send to segment | Default Subscribed Users. Any built-in segment or one you made in the dashboard. |
| Audience | Only browsers (default on) leaves out Android and iOS users of the same Pushix app. Untick it to send blog posts to your app users too. |
| Picture | Use the featured image as the notification picture. |
| Use my own service worker | Only for sites that already have one (see below). |
What the plugin adds
On every page, before </head>:
<script>
window.PushixDeferred = window.PushixDeferred || [];
window.PushixDeferred.push(function (Pushix) {
return Pushix.init({"appId":"YOUR_APP_ID","serverUrl":"https://pushix.in","serviceWorkerPath":"/pushix-sw.js","serviceWorkerParam":{"scope":"/"}});
});
</script>
<script src="https://pushix.in/sdk/pushix-web.js" defer></script>Nothing is added until the server URL and App ID are saved.
At /pushix-sw.js, served by WordPress through a rewrite rule (no file to upload):
importScripts("https://pushix.in/sdk/pushix-sw-core.js");It is sent as application/javascript with Service-Worker-Allowed: /. The rule is added when you activate the plugin and removed when you deactivate it.
In the post editor (block editor and classic editor), a Push notification box with:
- Send a push notification when this is published — ticked when "Send automatically" is on.
- Title — empty uses the site name.
- Message — empty uses the post title.
- After publishing: the result ("Sent 2 mins ago to 1,250 subscribers." or the error) and Send it again when I click Update.
Sending when you publish
The first time a post is published, the plugin sends:
{
"app_id": "YOUR_APP_ID",
"included_segments": ["Subscribed Users"],
"headings": {"en": "Site name or your title"},
"contents": {"en": "Post title or your message"},
"url": "https://yoursite.com/the-post/",
"big_picture": "https://yoursite.com/wp-content/uploads/featured.jpg",
"isAnyWeb": true,
"data": {"wp_post_id": 123},
"idempotency_key": "wp-…-123-1"
}to POST {server}/api/v1/notifications with Authorization: Basic YOUR_REST_API_KEY. Clicking the notification opens the post. The notification id (or the error) is saved with the post, and the editor shows the result.
- Never twice. Updating, unpublishing and publishing again, or editing from Quick Edit doesn't send again. Only ticking Send it again does. The idempotency key also stops duplicates if two requests race.
- Scheduled posts are sent when they go live, with what was in the box when you scheduled them.
- Block editor: the editor saves the post and then the box in a second request; the notification is sent in that second request, and the result appears as an editor notice.
- Posts published by other apps through the REST API, by WP-CLI or XML-RPC use the "Send automatically" setting. REST API posts are sent about a minute later by WP-Cron.
- Not sent: imported posts, password-protected posts (unless you tick Send it again), and post types you didn't select.
- A failed send can be retried with Send it again; the retry uses the same idempotency key, so it can't double-send if the first attempt got through after all.
WordPress in a subfolder
If your WordPress address is https://yoursite.com/blog/, the plugin serves the worker at /blog/pushix-sw.js and passes it to the SDK with the matching scope:
Pushix.init({ appId: "…", serviceWorkerPath: "/blog/pushix-sw.js", serviceWorkerParam: { scope: "/blog/" } });That covers every page of the WordPress site. Pages outside /blog/ need their own snippet and /pushix-sw.js (see WEB_SDK.md).
A site that already has a service worker
Browsers allow one service worker per scope, so a PWA or offline plugin and Pushix must share one file. Add this line at the top of your existing worker:
importScripts('https://pushix.in/sdk/pushix-sw-core.js');Then enter its path (for example /sw.js) under Settings → Pushix → Use my own service worker.
For developers
| Filter | |
|---|---|
pushix_post_payload | ($payload, $post) — change the notification sent for a post, e.g. add web_buttons or another segment. |
pushix_should_send | ($send, $post, $again) — return false to skip a post. |
pushix_init_options | ($options) — options passed to Pushix.init, e.g. autoPrompt or accentColor. |
pushix_load_sdk | ($load) — return false to leave the SDK off a page. |
To link subscribers to your WordPress users, call Pushix.login from your theme:
add_action( 'wp_footer', function () {
if ( is_user_logged_in() ) {
printf( '<script>window.PushixDeferred.push(function (Pushix) { Pushix.login(%s); });</script>', wp_json_encode( (string) get_current_user_id() ) );
}
} );Your backend can then send to them by user id with the server libraries.
Deleting the plugin from the Plugins screen removes its settings and post meta. Notifications already sent stay in Pushix.
Troubleshooting
/pushix-sw.jsshows a page or "not found" — open Settings → Permalinks and click Save Changes to rebuild WordPress's rewrite rules. With the permalink setting Plain there are no rewrite rules, so the plugin uses/?pushix_sw=1instead; choose any other setting to get the usual/pushix-sw.jsaddress.Nginx returns its own 404 for
/pushix-sw.js— a rule for static.jsfiles is answering before WordPress. Add this to the server block, above the rules for static files:Nginxlocation = /pushix-sw.js { try_files $uri /index.php?$args; }Caching and optimisation plugins (WP Rocket, LiteSpeed Cache, Autoptimize, W3 Total Cache, Cloudflare Rocket Loader) — exclude
pushix-web.jsand the inlinePushixDeferredscript from "combine", "minify", "defer" and "delay JavaScript until interaction" options, and exclude/pushix-sw.jsfrom page caching and CDN HTML caching. Clear the cache after changing Pushix settings.HTTPS — browsers only allow push on
https://sites, and anhttps://page can't load the SDK from anhttp://Pushix server. Both need valid certificates. (http://localhostworks while testing.)The prompt never shows — check Check connection first. The prompt waits for the delay and page views set in the dashboard, and hides for a few days after "Not now". Test in a private window.
"Pushix is not set up" in the editor — add the REST API key under Settings → Pushix.
"Last attempt failed: …" in the editor — the message comes from the Pushix server; API.md explains each field. Fix it, then tick Send it again and click Update.
Posts from other apps are sent late or not at all — they go out through WP-Cron about a minute after publishing. If
DISABLE_WP_CRONis set, make sure a real cron job callswp-cron.php.Content Security Policy — allow
https://pushix.ininscript-src,connect-srcandimg-src.
Send your first notification
Create an app in Pushix to get your App ID and REST API key, then follow this guide. The free plan needs no card.