CreateIT
CreateIT
BLOG

Gatsby push notifications solution

Ninja standing in front of a laptop with a notification box on screen

Gatsby push notifications solution

SHARE

Challenge:
add push notifications to a Gatsby website
Solution:
deploy a WordPress website on the same domain and use the self-hosted Perfecty Push Notifications WP plugin

GatsbyJS is a static website generator based on ReactJS. In a time when Headless CMS is a trending concept, Gatsby is becoming more popular. Having WordPress CMS Backend for data sourcing, you can set up a static website with Gatsby really fast! The benefits? Speed (good site performance), security, and low hosting costs.

Are you using GatsbyJS and would like to enable push notifications? You will find a solution in this article.

Self hosted push notifications

An interesting WordPress plugin for self-hosted push notifications is called Perfecty Push Notifications. Released on 26 Dec 2020 and frequently updated, the plugin is getting more popular and provides a nice set of features. More info: https://wordpress.org/plugins/perfecty-push-notifications/

Perfecty is self-hosted. All data is stored in a WordPress database locally. In contrast, third-party services like OneSignal store data in the cloud. OneSignal is free for small websites, but starting from 10.000 subscribers, it requires a paid plan. In this article, we will focus on a self-hosted solution.

Push notifications in Gatsby

The configuration of push notifications on a static Gatsby website requires a couple of steps:

  1. Configure a WordPress instance with the “Perfecty Push Notifications” plugin activated (needs to use the same domain like a Gatsby site to pass the CORS policy)
  2. integrate Gatsby with the Perfecty plugin (by adding Javascript initialization)
  3. minor tweaks in the Perfecty plugin (to skip nonce validation)

WordPress installation

WordPress will store all push notification data – users, content of notification and schedule sending – using Cron. It’s important to have a https connection (SSL certificate) and to use the same domain as the Gatsby website. For example:

The Perfecty plugin uses ajax calls to register a user and add a new subscriber to notifications (WP REST custom endpoints). Due to CORS policy, a “Gatsby site” and “Wordpress Backend for Push Notifications site” needs to use a common domain name.

Perfecty Push Notifications configuration

The activated plugin is ready to use. Your WordPress installation at https://www.example.com/mywordpress/ is now able to register new subscribers and send desktop push notifications. A visitor can also unsubscribe by using the bell icon placed in the bottom left corner.

WordPress Plugins section

Subscribe to notifications

The standard workflow for subscribing to push notifications of a WordPress site:

  1. Click the ‘Continue’ button
  2. Confirm ‘Allow’ in the ‘Show notifications’ browser alert
  3. That’s it. The user is subscribed to future browser pushes. By default, the user will receive a ‘welcome message’: Congratulations, you’re now subscribed! Texts can be changed in the WordPress plugin settings.

Pop up window with text over a sample website

A notification window with text

Unsubscribe

In case a user would like to stop receiving push notifications, there is a bell icon with a checkbox for unsubscribing. Unchecking the checkbox will trigger the unsubscribe action and remove the user from WordPress database.

White box with text and an orange button with a white bell icon

A windows notification for Google Chrome

Backend for sending notifications

Perfecty has an advanced admin panel for managing push notifications: a list of subscribers, a list of scheduled messages, and the ability to send new messages. It is also built with performance in mind.

For testing purposes, we’ve added one subscriber, then sent a test message as a push notification. In the following screenshots you will see the entire process.

WordPress dashboard

Notification details in WordPress dashboard

Red flower with green background and a notification below

Verification of sending messages

The plugin section ‘Notification jobs’ contains a list of all messages and statistics on how many succeeded (were received by subscribers). Messages are sent in the background using WordPress Cron.

According to authors, the plugin can send around 13.000 notifications in 1 minute (DigitalOcean droplet with 2 Gb of RAM and 2vCPU). The parameters that were used:

batch_size = 15.000

parallel_flushing_size = 200

memory_limit = 256M

max_execution_time = 256

Notification jobs window for WordPress

Gatsby implementation

Push notifications work in our WordPress, which is installed at: https://www.example.com/mywordpress/ . But what about Gatsby? How to enable push notifications at our Gatsby website? Here are those steps to enable Gatsby push notifications:

  1. hardcode plugin settings as object: window.PerfectyPushOptions (gatsby-browser.js)
  2. load a javascript file for initialization – perfecty-push-sdk.min.js (enqueuing file from wordpress folder)
  3. load the plugin stylesheet for styling (perfecty-push-public.css)

Here are examples of a working implementation:

// gatsby-browser.js
const addScript = url => {
    const script = document.createElement("script")
    script.src = url
    script.async = false
    document.body.appendChild(script)
}
exports.onClientEntry = () => {
    window.PerfectyPushOptions = {
        path: "https://www.example.com/mywordpress/wp-content/plugins/perfecty-push-notifications/public/js",
        dialogTitle: "Do you want to receive notifications?",
        dialogSubmit: "Continue",
        dialogCancel: "Not now",
        settingsTitle: "Notifications preferences",
        settingsOptIn: "I want to receive notifications",
        settingsUpdateError: "Could not change the preference, try again",
        serverUrl: "https://www.example.com/mywordpress/admin/wp-json/perfecty-push",
        vapidPublicKey: "BF2RuUdxpxX1JPNOdT5YasmDlZU21mvwFjeTUXKT50-yqvMFqx0LIuYuGi-lLlKX0AZcG6nt_zapSaxpCxO8ZYo",
        token: "da3212edsa",
        tokenHeader: "X-WP-Nonce",
        token2: "da831edDS23ds234Jaa",
        enabled: true,
        unregisterConflicts: false,
        serviceWorkerScope: "/perfecty/push",
        loggerLevel: "error",
        loggerVerbose: false,
        hideBellAfterSubscribe: false,
        askPermissionsDirectly: false,
        unregisterConflictsExpression: "(OneSignalSDKWorker|wonderpush-worker-loader|webpushr-sw|subscribers-com/firebase-messaging-sw|gravitec-net-web-push-notifications|push_notification_sw)",
        promptIconUrl: "",
        visitsToDisplayPrompt: 0
    }
    addScript("https://www.example.com/mywordpress/wp-content/plugins/perfecty-push-notifications/public/js/perfecty-push-sdk/dist/perfecty-push-sdk.min.js?ver=1.6.1")
}

You might ask: where can I find my window.PerfectyPushOptions object with settings? The plugin adds it as a global javascript variable in the WordPress DOM, just navigate to: view-source: https://www.example.com/mywordpress/ – and there will be a variable there, defined with all the current plugin settings. Just copy it to GatsbyJS.

For applying styling, we will add a css file in the Helmet tag section:

// src/components/Sections/Layout.js
const Layout = (props) => {
   return (
      <>
         <SEO title={props.pageTitle} description={t('siteMetadata.description')} article={props.article} errorPage={props.errorPage} />
         <Helmet>
            <link rel='stylesheet' id='perfecty-push-css' href='https://www.example.com/mywordpress/wp-content/plugins/perfecty-push-notifications/public/css/perfecty-push-public.css?ver=1.6.1' media='all' />
         </Helmet>
         {props.children}
      </>
   );
}
export default Layout;

Fix WP Nonce error

The plugin is doing a verification of nonce (a secret value added in the request that is refreshed every X hours). We have hardcoded the nonce value in the gatsby-browser.js file, so it will be outdated really soon. As a result, the AJAX request will be blocked on the WordPress side with the error: “Cookie nonce is invalid”.

We don’t have an elegant solution for this issue. The only way is to edit the plugin source code and disable nonce validation. We need to add 3 changes in the wp-content/plugins/perfecty-push-notifications/public/class-perfecty-push-users.php file:

Find:

if ( wp_verify_nonce( $nonce, 'wp_rest' ) === false ) {
   $this->terminate();
}

and replace it with:

if($nonce === 'da3212edsa'){
    // do nothing
} else {
    if ( wp_verify_nonce( $nonce, 'wp_rest' ) === false ) {
        $this->terminate();
    }
}

This will disable nonce validation for 3 endpoints: register user, get user subscriber status and unregister user. By adding those changes Gatsby will be able to communicate with the WordPress installation (our Backend for Push Notifications).

Black window with colorful code fragments

WP REST API nonce validation

We are almost done with implementation. The last remaining problem is: currently WP REST API endpoints is still blocking requests from Gatsby. The reason is that before executing plugin endpoints, WordPress validates the X-WP-Nonce header value and returns the 403 error (forbidden).

The solution for this issue: create a new WordPress user (subscriber) and set up Application Passwords in Edit User settings. This value will be set in Gatsby as token2 and passed to WP REST API for Basic Authorization.

Application Passwords settings in WordPress window with code on the right

For handling the token2 value inside the plugin we need to edit: wp-content/plugins/perfecty-push-notifications/public/js/perfecty-push-sdk/dist/perfecty-push-sdk.min.js . It’s minified by default, so first, we’re going to prettify js file for better readability.

First change, add token2 to the list of passed parameters. Find:

S.token = e.token

and replace it with:

S.token = e.token, S.token2 = e.token2

Second change, add Basic Authorization. Find:

var e = {"Content-Type": "application/json"};
return e[E.tokenHeader] = E.token, e

and replace it with:

var username = 'user-for-gatsby-1';
var token2 = btoa(username + ':' + E.token2);
var e = {"Content-Type": "application/json", 'Authorization': 'Basic ' + token2};
return e[E.tokenHeader] = E.token, e

Make sure to update the username value (it’s a new user just added in WordPress users section). This user has application password set up and is used only for authentication purposes.

Gatsby PWA with notifications

That’s it! We have managed to enable push notifications for our Gatsby website

To make it behave like a native mobile app, including offline mode and android push notifications, we need to set up the Progressive Web App (PWA). A PWA website with Gatsby is simple, we need to install 2 plugins: gatsby-plugin-manifest and gatsby-plugin-offline. Here is the result, a notification received on the Android mobile phone:

Android settings and notifications screen with a laptop picture

Safari and push notification

The most anticipated feature for Safari iOS is web push notifications. Currently, it’s not possible to get web push notifications on iPads and iPhones. With iOS 16, Apple is confirming that notifications will be supported. The official release is expected in fall 2022.

Troubleshooting

  • Problem: I see a critical error on Perfecty plugin activation
  • Solution: The plugin required a PHP gmp extension (GNU Multiple Precision) to be installed on the server. More info: https://docs.perfecty.org/wp/troubleshooting/ .

That’s it for today’s Support Diaries. Subscribe to our newsletter to stay up to date with all the news and guidelines.

 

Need help?

  • Looking for support from experienced programmers?

  • Need to fix a bug in the code?

  • Want to customize your webste/application?

ADD COMMENT

Your email address will not be published.

createIT Contact