Implementando Notificações Push com a Web Push API

As notificações push mantêm os usuários engajados mesmo quando não estão usando ativamente sua aplicação web. A Web Push API permite enviar atualizações oportunas diretamente para os dispositivos dos usuários sem depender de serviços de terceiros. Este guia mostra como implementar notificações nativas usando Service Workers, autenticação VAPID e criptografia adequada.
Pontos-Chave
- A Web Push API permite notificações push nativas sem serviços de terceiros
- Service Workers e autenticação VAPID são componentes essenciais
- Conexão HTTPS é obrigatória para implementação
- Diferentes navegadores têm requisitos variados para notificações push
Pré-requisitos e Suporte dos Navegadores
Antes de implementar notificações push, certifique-se de que sua aplicação atende a estes requisitos:
- Conexão HTTPS (necessária para Service Workers)
- Suporte de navegadores modernos (Chrome, Firefox, Edge, Safari 16.4+)
- Compatibilidade com Service Worker
// Feature detection
if ('serviceWorker' in navigator && 'PushManager' in window) {
// Push notifications supported
}
Registrando um Service Worker
O Service Worker atua como um proxy entre sua aplicação web e os serviços push. Registre-o durante o carregamento da página:
navigator.serviceWorker.register('/sw.js')
.then(registration => {
console.log('Service Worker registered:', registration);
})
.catch(error => {
console.error('Registration failed:', error);
});
Configurando Chaves VAPID
VAPID (Voluntary Application Server Identification) autentica seu servidor com os serviços push. Gere um par de chaves uma vez para sua aplicação:
# Using web-push library (Node.js)
npm install web-push
npx web-push generate-vapid-keys
Armazene a chave privada de forma segura em seu servidor e use a chave pública na assinatura do lado do cliente.
Criando Assinaturas Push
Solicite permissão e inscreva os usuários para receber notificações push:
async function subscribeToPush() {
const registration = await navigator.serviceWorker.ready;
// Request permission (only on user gesture)
const permission = await Notification.requestPermission();
if (permission !== 'granted') return;
// Subscribe with VAPID public key
const subscription = await registration.pushManager.subscribe({
userVisibleOnly: true,
applicationServerKey: urlBase64ToUint8Array(VAPID_PUBLIC_KEY)
});
// Send subscription to your server
await fetch('/api/subscribe', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(subscription)
});
}
// Helper function to convert base64 to Uint8Array
function urlBase64ToUint8Array(base64String) {
const padding = '='.repeat((4 - base64String.length % 4) % 4);
const base64 = (base64String + padding)
.replace(/\-/g, '+')
.replace(/_/g, '/');
const rawData = window.atob(base64);
const outputArray = new Uint8Array(rawData.length);
for (let i = 0; i < rawData.length; ++i) {
outputArray[i] = rawData.charCodeAt(i);
}
return outputArray;
}
O objeto de assinatura contém:
- Endpoint: URL única para envio de mensagens
- Keys: Chaves de criptografia (p256dh e auth) para segurança do payload
Discover how at OpenReplay.com.
Implementação no Lado do Servidor
Seu servidor deve criptografar mensagens e enviá-las para o endpoint do serviço push. Usar a biblioteca web-push simplifica isso:
const webpush = require('web-push');
webpush.setVapidDetails(
'mailto:your-email@example.com',
VAPID_PUBLIC_KEY,
VAPID_PRIVATE_KEY
);
// Send notification
const payload = JSON.stringify({
title: 'New Message',
body: 'You have a new update',
icon: '/icon-192.png',
url: 'https://example.com/updates'
});
webpush.sendNotification(subscription, payload, {
TTL: 86400, // 24 hours
urgency: 'high'
})
.catch(error => {
console.error('Error sending notification:', error);
});
Manipulando Eventos Push no Service Worker
O Service Worker recebe e exibe notificações push:
// sw.js
self.addEventListener('push', event => {
const data = event.data?.json() || {};
const options = {
body: data.body || 'Default message',
icon: data.icon || '/icon.png',
badge: '/badge.png',
vibrate: [200, 100, 200],
data: { url: data.url }
};
event.waitUntil(
self.registration.showNotification(data.title || 'Notification', options)
);
});
// Handle notification clicks
self.addEventListener('notificationclick', event => {
event.notification.close();
event.waitUntil(
clients.openWindow(event.notification.data?.url || '/')
);
});
Requisitos Específicos dos Navegadores
Diferentes navegadores impõem requisitos variados para a implementação da Web Push API:
- Chrome/Edge: Exigem notificações visíveis para cada mensagem push
- Firefox: Permite push silencioso limitado com sistema de cota
- Safari: Requer notificações visíveis e não suporta push silencioso
Observação: Os tamanhos de payload são limitados: Chrome/Edge/Firefox suportam até 4KB, enquanto o Safari suporta 2KB. Mantenha as mensagens leves e busque dados adicionais na aplicação, se necessário.
Sempre exiba notificações imediatamente ao receber eventos push para manter as permissões em todos os navegadores.
Melhores Práticas de Segurança
Proteja sua implementação de notificações push:
- Endpoints seguros: Nunca exponha endpoints de assinatura publicamente
- Criptografe payloads: Todos os dados de mensagem devem usar criptografia ECDH
- Proteja chaves VAPID: Armazene-as com segurança e regenere apenas se comprometidas
- Implemente proteção CSRF: Valide solicitações de assinatura
- Limitação de taxa: Previna abusos com throttling no lado do servidor
Gerenciando o Ciclo de Vida da Assinatura
Lide com mudanças e expiração de assinatura:
// In Service Worker
self.addEventListener('pushsubscriptionchange', event => {
event.waitUntil(
self.registration.pushManager.subscribe({
userVisibleOnly: true,
applicationServerKey: urlBase64ToUint8Array(VAPID_PUBLIC_KEY)
})
.then(subscription => {
// Update server with new subscription
return fetch('/api/update-subscription', {
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(subscription)
});
})
);
});
Conclusão
A Web Push API fornece uma abordagem baseada em padrões para implementar notificações push sem dependência de fornecedores. Ao combinar Service Workers, autenticação VAPID e criptografia adequada, você pode entregar notificações oportunas que funcionam em navegadores modernos. Lembre-se de respeitar as preferências dos usuários, lidar com eventos do ciclo de vida da assinatura e seguir requisitos específicos da plataforma para uma implementação robusta.
Comece com entrega básica de notificações e depois adicione recursos como botões de ação, anexos de imagem e agrupamento de notificações conforme sua implementação amadurece.
Perguntas Frequentes
Não, as notificações push requerem uma conexão ativa com a internet para receber mensagens do serviço push. No entanto, Service Workers podem armazenar notificações em cache e exibi-las quando a conectividade retornar.
Quando a permissão é negada, você não pode enviar notificações push para esse usuário. Você deve aguardar que ele altere manualmente as permissões nas configurações do navegador. Considere implementar métodos alternativos de engajamento, como notificações dentro da aplicação.
A maioria dos serviços push limita o tamanho do payload a 4KB. Chrome e Firefox suportam até 4KB, enquanto o Safari suporta até 2KB. Mantenha os payloads mínimos e busque dados adicionais quando a notificação for recebida, se necessário.
Sim, notificações push podem ser recebidas quando o navegador está fechado na maioria das plataformas. No entanto, isso depende do sistema operacional e do navegador. Navegadores móveis podem ter restrições baseadas em configurações de otimização de bateria.
Understand every bug
Uncover frustrations, understand bugs and fix slowdowns like never before with OpenReplay — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data. Check our GitHub repo and join the thousands of developers in our community.