How we implemented push notifications on our website

Too many websites use push notifications irresponsibly. They will prompt users to signup the moment they visit the site, without providing any value to people first.

This not only hurts the user experience, it’s also a risky business. If a user denies a site access at the start, that site might not be able to ask for it again, as permission will be blocked (In Chrome).

This is not to say push notifications are a bad technology in itself. When used responsibly, they offer a way to form a connection between people and the content they want.

Image taken by Igor Ovsyannykov - Manali, India (

Our Approach

We wanted a responsible way of using push notifications on our website. At the end of each blog post, we show these buttons to allow guests to get notified when new posts arrive.


When people click the notification button, the browser will prompt for permissions:


At any time, users have the ability to turn off notifications on the website after signing up.

Notifications Turned Off

Under the hood

There is both front and back-end logic behind the solution. The front-end has a Service Worker to listen to messages when people are not browsing the site. Meanwhile, the back-end stores subscriptions and sends messages to its registered browsers.

Instead of building all this ourselves, we decided to use OneSignal as our push notification provider. OneSignal enables us to easily send messages, manage subscriptions and more.

OneSignal has an additional support for Safari on macOS that uses a non-standard way for push notifications. Here is the complete browser support:

Source: OneSignal website
Source: OneSignal website

The browser support will broaden further going forward.

Show me the code!

The OneSignal documentation is quite good. However, it doesn’t include a full example for our approach, so let’s go through it in this post.

As a start, we added OneSignal to our site.

<script src="" async></script>
var OneSignal = window.OneSignal || [];

Notice the async keyword to prevent the script from blocking rendering of the page. All of OneSignal calls are in-fact asynchronous.

Calling init

The next step is to initialise OneSignal.

OneSignal.push(() => {
    appId: "<APP_ID>",
    safari_web_id: '<SAFARI_WEB_ID>',
    autoRegister: false,
    allowLocalhostAsSecureOrigin: true,
    welcomeNotification: {
      title: '14islands',
      message: 'We will keep you posted!'
    promptOptions: {},
    notifyButton: { enable: false }

We got app_id and safari_id under the App Settings in the OneSignal Dashboard after creating a new app in there.

The allowLocalhostAsSecureOrigin: true flag will treat http://localhost and as a secure origin. In production, push notifications require HTTPS to work.

It’s important not to call the init method more than once. Doing so results in an error.

Progressive enhancement

Push notifications are not supported by all browsers. For those browsers, we only show the newsletter signup form on our website - in a true progressive enhancement fashion.

The newsletter signup form works on all browsers and even without JavaScript enabled.

Notifications & Newsletter

Next, we check if there is support and show the notification button in those cases.

OneSignal.push(() => {
	this.showNotfications = OneSignal.isPushNotificationsSupported()
	if (this.showNotfications) {

In the CSS, the show-notifications class will switch to the view showing both buttons.



When people click the “Get Notification” button they will be subscribed.

OneSignal.push(() => {

A welcome notification is sent out at this point. It’s a nice way to give feedback to people that they are now receiving notifications.


In the constructor, we have the following code to detect if the user is subscribed and respond to subscription changes.

OneSignal.push(() => {
	// Check if subscribed on load
	OneSignal.isPushNotificationsEnabled().then((isSubscribed) => {
		this.$context.toggleClass('is-subscribed-to-push', isSubscribed)
	// Check if user hits the subscribe button
	OneSignal.on('subscriptionChange', (isSubscribed) => {
		this.$context.toggleClass('is-subscribed-to-push', isSubscribed)

In the CSS, the is-subscribed-to-push will show the “Turn off Notification” button.

Notifications Turned Off

Turn off notification

People unregister when they click the “Turn off” button.

new window.Notification('14islands', {
	body: 'Notifications are now turned off.',
	icon: '/icons/android-chrome-192x192.png'
OneSignal.push(() => {

We send out a notification using the standard Notification API. This is nice to give the user feedback for unregistering.


To summarize

Users should show intent before a site asks for a permission, and allow users easily to turn notifications off.

You can try out our implementation under the comments section below.

Write a comment

Keep me posted!