Como mostrar uma notificação

As opções de notificação são divididas em duas seções: uma que lida com os aspectos visuais (esta seção) e outra que explica os aspectos comportamentais das notificações (a próxima seção).

Você pode testar várias opções de notificação em diversos navegadores e plataformas usando o Notification Generator de Peter Beverloo.

Opções visuais

A API para mostrar uma notificação é simples:

<ServiceWorkerRegistration>.showNotification(<title>, <options>);

Os argumentos title e options são opcionais.

O título é uma string, e as opções podem ser qualquer uma das seguintes:

{
  "//": "Visual Options",
  "body": "<String>",
  "icon": "<URL String>",
  "image": "<URL String>",
  "badge": "<URL String>",
  "dir": "<String of 'auto' | 'ltr' | 'rtl'>",
  "timestamp": "<Long>"

  "//": "Both visual & behavioral options",
  "actions": "<Array of Strings>",
  "data": "<Anything>",

  "//": "Behavioral Options",
  "tag": "<String>",
  "requireInteraction": "<boolean>",
  "renotify": "<Boolean>",
  "vibrate": "<Array of Integers>",
  "sound": "<URL String>",
  "silent": "<Boolean>",
}

Vamos conferir as opções visuais:

Análise da interface de uma notificação.

Opções de título e corpo

Veja como é uma notificação sem o título e as opções no Chrome no Windows:

Notificação sem o título e as opções no Chrome no Windows.

Como você pode ver, o nome do navegador é usado como título, e o marcador de posição "Nova notificação" é usado como o corpo da notificação.

Se um aplicativo da Web progressivo estiver instalado no dispositivo, o nome do app da Web será usado em vez do nome do navegador:

Notificação com o nome do app da Web em vez do nome do navegador.

Se executarmos o seguinte código:

const title = 'Simple Title';

const options = {
  body: 'Simple piece of body text.\nSecond line of body text :)',
};

registration.showNotification(title, options);

receberíamos esta notificação no Chrome no Linux:

Notificação com título e corpo do texto no Chrome no Linux.

No Firefox no Linux, o resultado seria assim:

Notificação com título e corpo de texto no Firefox no Linux.

Esta é a aparência da notificação com muito texto no título e no corpo no Chrome no Linux:

Notificação com título e corpo de texto longos no Chrome no Linux.

O Firefox no Linux recolhe o texto do corpo até que você passe o cursor sobre a notificação, fazendo com que ela se expanda:

Notificação com título e corpo de texto longos no Firefox no Linux.

Notificação com título e corpo de texto longos no Firefox no Linux ao passar o cursor do mouse sobre a notificação.

As mesmas notificações no Firefox no Windows têm esta aparência:

Notificação com título e corpo de texto no Firefox no Windows.

Notificação com título e corpo de texto longos no Firefox no Windows.

Como você pode ver, a mesma notificação pode ter uma aparência diferente em navegadores diferentes. Ele também pode parecer diferente no mesmo navegador em plataformas diferentes.

O Chrome e o Firefox usam as notificações do sistema e a central de notificações em plataformas em que esses recursos estão disponíveis.

Por exemplo, as notificações do sistema no macOS não são compatíveis com imagens e ações (botões e respostas inline).

O Chrome também tem notificações personalizadas para todas as plataformas de computador. Para ativá-lo, defina a flag chrome://flags/#enable-system-notifications como o estado Disabled.

Ícone

A opção icon é basicamente uma imagem pequena que pode ser mostrada ao lado do título e do texto do corpo.

No código, é necessário fornecer um URL para a imagem que você quer carregar:

const title = 'Icon Notification';

const options = {
  icon: '/images/demos/icon-512x512.png',
};

registration.showNotification(title, options);

Você vai receber esta notificação no Chrome no Linux:

Notificação com ícone no Chrome no Linux.

e no Firefox no Linux:

Notificação com ícone no Firefox no Linux.

Infelizmente, não há diretrizes sólidas sobre o tamanho da imagem a ser usada em um ícone.

O Android parece querer uma imagem de 64 dp (que é 64 px multiplicados pela proporção de pixels do dispositivo).

Supondo que a maior proporção de pixels para um dispositivo seja 3, um tamanho de ícone de 192 px ou mais é uma aposta segura.

Selo

O badge é um pequeno ícone monocromático usado para mostrar ao usuário mais informações sobre a origem da notificação:

const title = 'Badge Notification';

const options = {
  badge: '/images/demos/badge-128x128.png',
};

registration.showNotification(title, options);

No momento em que este artigo foi escrito, o selo só é usado no Chrome para Android.

Notificação com selo no Chrome para Android.

Em outros navegadores (ou no Chrome sem o selo), você vai ver um ícone do navegador.

Notificação com selo no Firefox para Android.

Assim como na opção icon, não há diretrizes reais sobre o tamanho a ser usado.

Analisando as diretrizes do Android, o tamanho recomendado é de 24 px multiplicado pela proporção de pixels do dispositivo.

Isso significa que uma imagem de 72 px ou mais é suficiente (considerando uma proporção máxima de pixels do dispositivo de 3).

Imagem

A opção image pode ser usada para mostrar uma imagem maior ao usuário. Isso é particularmente útil para mostrar uma imagem de visualização ao usuário.

const title = 'Image Notification';

const options = {
  image: '/images/demos/unsplash-farzad-nazifi-1600x1100.jpg',
};

registration.showNotification(title, options);

No Chrome para Linux, a notificação será assim:

Notificação com imagem no Chrome no Linux.

No Chrome para Android, o corte e a proporção são diferentes:

Notificação com imagem no Chrome para Android.

Devido às diferenças na proporção entre computadores e dispositivos móveis, é extremamente difícil sugerir diretrizes.

Como o Chrome para computador não preenche o espaço disponível e tem uma proporção de 4:3, talvez a melhor abordagem seja veicular uma imagem com essa proporção e permitir que o Android a corte. Dito isso, a opção image ainda pode mudar.

No Android, a única diretriz é uma largura de 450 dp.

Seguindo essa diretriz, uma imagem com largura de 1.350 px ou mais seria uma boa opção.

Ações (botões)

É possível definir actions para exibir botões com uma notificação:

const title = 'Actions Notification';

const options = {
  actions: [
    {
      action: 'coffee-action',
      type: 'button',
      title: 'Coffee',
      icon: '/images/demos/action-1-128x128.png',
    },
    {
      action: 'doughnut-action',
      type: 'button',
      title: 'Doughnut',
      icon: '/images/demos/action-2-128x128.png',
    },
    {
      action: 'gramophone-action',
      type: 'button',
      title: 'Gramophone',
      icon: '/images/demos/action-3-128x128.png',
    },
    {
      action: 'atom-action',
      type: 'button',
      title: 'Atom',
      icon: '/images/demos/action-4-128x128.png',
    },
  ],
};

registration.showNotification(title, options);

Para cada ação, é possível definir um title, um action (que é basicamente um ID), um icon e um type. O título e o ícone são o que você vê na notificação. O ID é usado para detectar que o botão de ação foi clicado (mais informações sobre isso na próxima seção). O tipo pode ser omitido porque 'button' é o valor padrão.

No momento, apenas o Chrome e o Opera para Android são compatíveis com ações.

No exemplo acima, há quatro ações definidas para ilustrar que é possível definir mais ações do que serão exibidas. Se você quiser saber o número de ações que serão exibidas pelo navegador, verifique window.Notification?.maxActions:

const maxVisibleActions = window.Notification?.maxActions;

if (maxVisibleActions) {
  options.body = `Up to ${maxVisibleActions} notification actions can be displayed.`;
} else {
  options.body = 'Notification actions are not supported.';
}

No computador, os ícones dos botões de ação mostram as cores (veja a rosquinha rosa):

Notificação com botões de ação no Chrome no Linux.

No Android 6 e versões anteriores, os ícones são coloridos para combinar com o esquema de cores do sistema:

Notificação com botões de ação no Google Chrome para Android.

No Android 7 e versões mais recentes, os ícones de ação não são mostrados.

Esperamos que o Chrome mude o comportamento no computador para corresponder ao Android, ou seja, aplique o esquema de cores adequado para que os ícones correspondam à aparência do sistema. Enquanto isso, você pode usar a cor de texto do Chrome, fazendo com que os ícones tenham a cor #333333.

Também vale a pena mencionar que os ícones ficam nítidos no Android, mas não no computador.

O melhor tamanho que consegui para o Chrome para computador foi 24 x 24 px. Infelizmente, isso não fica bem no Android.

A prática recomendada que podemos extrair dessas diferenças:

  • Use um esquema de cores consistente para que todos os ícones sejam exibidos de forma consistente para o usuário.
  • Verifique se eles funcionam em monocromático, já que algumas plataformas podem exibi-los dessa forma.
  • Teste o tamanho e veja o que funciona para você. 128 px × 128 px funciona bem no Android, mas tem baixa qualidade no computador.
  • Os ícones de ação não serão exibidos.

A especificação de notificação está explorando uma maneira de definir vários tamanhos de ícones, mas parece que vai levar algum tempo até que algo seja acordado.

Ações (respostas inline)

É possível adicionar uma resposta inline à notificação definindo uma ação com o tipo 'text':

const title = 'Alexey Rodionov';

const options = {
  body: 'How are you doing? )',
  image: '/images/demos/avatar-512x512.jpg',
  icon: '/images/demos/icon-512x512.png',
  badge: '/images/demos/badge-128x128.png',
  actions: [
    {
      action: 'reply',
      type: 'text',
      title: 'Reply',
      icon: '/images/demos/action-5-128x128.png',
    }
  ],
};

registration.showNotification(title, options);

No Android, vai ficar assim:

Notificação no Android com um botão de ação de resposta.

Ao clicar no botão de ação, um campo de entrada de texto é aberto:

Notificação no Android com um campo de entrada de texto aberto.

É possível personalizar o marcador de posição do campo de entrada de texto:

const title = 'Alexey Rodionov';

const options = {
  body: 'How are you doing? )',
  icon: '/images/demos/avatar-512x512.jpg',
  badge: '/images/demos/badge-128x128.png',
  actions: [
    {
      action: 'reply',
      type: 'text',
      title: 'Reply',
      icon: '/images/demos/action-5-128x128.png',
      placeholder: 'Type text here',
    }
  ],
};

registration.showNotification(title, options);

Notificação no Android com marcador de posição personalizado para o campo de entrada de texto.

No Chrome para Windows, o campo de entrada de texto fica sempre visível, sem que seja necessário clicar no botão de ação:

Notificação no Windows com um campo de entrada de texto e um botão de ação de resposta.

É possível adicionar mais de uma resposta inline ou combinar botões e respostas inline:

const title = 'Poll';

const options = {
  body: 'Do you like this photo?',
  image: '/images/demos/cat-image.jpg',
  icon: '/images/demos/icon-512x512.png',
  badge: '/images/demos/badge-128x128.png',
  actions: [
    {
      action: 'yes',
      type: 'button',
      title: '👍 Yes',
    },
    {
      action: 'no',
      type: 'text',
      title: '👎 No (explain why)',
      placeholder: 'Type your explanation here',
    },
  ],
};

registration.showNotification(title, options);

Notificação no Windows com um campo de entrada de texto e dois botões de ação.

Direção

O parâmetro dir permite definir em qual direção o texto será exibido, da direita para a esquerda ou da esquerda para a direita.

Nos testes, pareceu que a direção era determinada principalmente pelo texto, e não por esse parâmetro. De acordo com a especificação, isso serve para sugerir ao navegador como organizar opções como ações, mas não vi diferença.

É melhor definir se você puder. Caso contrário, o navegador vai fazer o que é certo de acordo com o texto fornecido.

O parâmetro precisa ser definido como auto, ltr ou rtl.

Um idioma escrito da direita para a esquerda usado no Chrome no Linux tem esta aparência:

Notificação com idioma da direita para a esquerda no Chrome no Linux.

No Firefox (ao passar o cursor sobre ele), você verá o seguinte:

Notificação com idioma escrito da direita para a esquerda no Firefox no Linux.

Vibrar

A opção de vibração permite definir um padrão de vibração que será executado quando uma notificação for mostrada, supondo que as configurações atuais do usuário permitam vibrações (ou seja, o dispositivo não está no modo silencioso).

O formato da opção de vibração precisa ser uma matriz de números que descrevem o número de milissegundos que o dispositivo deve vibrar, seguido pelo número de milissegundos que o dispositivo não deve vibrar.

const title = 'Vibrate Notification';

const options = {
  // Star Wars shamelessly taken from the awesome Peter Beverloo
  // https://tests.peter.sh/notification-generator/
  vibrate: [
    500, 110, 500, 110, 450, 110, 200, 110, 170, 40, 450, 110, 200, 110, 170,
    40, 500,
  ],
};

registration.showNotification(title, options);

Isso só afeta os dispositivos que têm suporte à vibração.

Som

O parâmetro de som permite definir um som para tocar quando a notificação for recebida.

Até o momento, nenhum navegador oferece suporte a essa opção.

const title = 'Sound Notification';

const options = {
  sound: '/demos/notification-examples/audio/notification-sound.mp3',
};

registration.showNotification(title, options);

Carimbo de data/hora

O carimbo de data/hora permite que você informe à plataforma o momento em que ocorreu um evento que resultou no envio da notificação push.

O timestamp precisa ser o número de milissegundos desde 00:00:00 UTC, que é 1º de janeiro de 1970 (a época Unix).

const title = 'Timestamp Notification';

const options = {
  body: 'Timestamp is set to "01 Jan 2000 00:00:00".',
  timestamp: Date.parse('01 Jan 2000 00:00:00'),
};

registration.showNotification(title, options);

Práticas recomendadas de UX

A maior falha de UX que já vi com notificações é a falta de especificidade nas informações exibidas por uma notificação.

Considere o motivo de você ter enviado a mensagem push e verifique se todas as opções de notificação são usadas para ajudar os usuários a entender por que estão lendo essa notificação.

Para ser sincero, é fácil ver exemplos e pensar "eu nunca cometeria esse erro". Mas é mais fácil cair nessa armadilha do que você imagina.

Algumas armadilhas comuns a serem evitadas:

  • Não coloque o site no título ou no corpo. Os navegadores incluem seu domínio na notificação, então não o duplique.
  • Use todas as informações disponíveis. Se você enviar uma mensagem push porque alguém enviou uma mensagem para um usuário, em vez de usar o título "Nova mensagem" e o corpo "Clique aqui para ler", use o título "João acabou de enviar uma nova mensagem" e defina o corpo da notificação como parte da mensagem.

Navegadores e detecção de recursos

No momento em que este artigo foi escrito, havia uma grande disparidade entre o Chrome e o Firefox em termos de suporte a recursos para notificações.

Felizmente, é possível detectar a compatibilidade com recursos de notificação analisando o protótipo window.Notification.

Digamos que queremos saber se uma notificação é compatível com botões de ação. Para isso, fazemos o seguinte:

if ('actions' in window.Notification?.prototype) {
  // Action buttons are supported.
} else {
  // Action buttons are NOT supported.
}

Com isso, podemos mudar a notificação que mostramos aos usuários.

Com as outras opções, basta fazer o mesmo que acima, substituindo 'actions' pelo nome do parâmetro desejado.

A seguir

Code labs