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 vários navegadores em várias plataformas usando o Notification Generator do Peter Beverloo.

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

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

Os dois argumentos, title e options, são opcionais.

O título é uma string, e as opções podem ser 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>",
}

Vejamos as opções visuais:

Dissecção da UI de uma notificação.

Opções de título e corpo

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

Notificação sem título e 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 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);

Recebemos esta notificação no Chrome no Linux:

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

No Firefox para Linux, seria assim:

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

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

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

O Firefox no Linux reduz o texto do corpo até você passar o cursor sobre a notificação, fazendo com que ela seja expandida:

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

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

As mesmas notificações no Firefox no Windows ficam assim:

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

Notificação com título longo e texto do corpo 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 ter uma aparência diferente no mesmo navegador em plataformas diferentes.

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

Por exemplo, as notificações do sistema no macOS não oferecem suporte a imagens e ações (botões e respostas inline).

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

Ícone

A opção icon é essencialmente uma pequena imagem que você pode mostrar ao lado do título e do corpo do texto.

No código, você precisa fornecer um URL para a imagem que quer carregar:

const title = 'Icon Notification';

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

registration.showNotification(title, options);

Você recebe 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 para um ícone.

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

Supondo que a proporção de pixels mais alta 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 mais informações ao usuário 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 é usado apenas no Chrome no Android.

Notificação com crachá no Chrome no Android.

Em outros navegadores (ou no Chrome sem o selo), você 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.

De acordo com as diretrizes do Android, o tamanho recomendado é de 24 pixels multiplicado pela proporção de pixels do dispositivo.

Ou seja, uma imagem de 72 px ou mais deve ser boa (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 vai ficar 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 de proporção entre computadores e dispositivos móveis, é extremamente difícil sugerir diretrizes.

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

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

Usando essa diretriz, uma imagem de largura de 1.350 px ou mais seria uma boa aposta.

Ações (botões)

Você pode definir actions para mostrar 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, você pode definir um title, um action (que é essencialmente 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 se 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 da escrita, apenas o Chrome e o Opera para Android oferecem suporte a 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, confira 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 do botão de ação mostram as cores (veja o donut 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.

O Chrome vai mudar o comportamento no computador para combinar com o Android (ou seja, aplicar o esquema de cores apropriado para que os ícones combinem com a aparência do sistema). Enquanto isso, é possível combinar a cor do texto do Chrome fazendo com que os ícones tenham a cor #333333.

Vale ressaltar que os ícones têm aparência nítida no Android, mas não no computador.

O melhor tamanho que eu conseguia trabalhar no Chrome para computadores era 24 x 24 pixels. Isso parece fora do lugar no Android.

A melhor prática que podemos tirar dessas diferenças:

  • Use um esquema de cores consistente para que pelo menos todos os ícones sejam mostrados de forma consistente ao usuário.
  • Confira 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 x 128 pixels funciona bem no Android, mas a qualidade era ruim no computador.
  • Os ícones de ação não vão aparecer.

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

Ações (respostas inline)

É possível adicionar uma resposta in-line à 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);

Confira como vai ficar no Android:

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

Clicar no botão de ação abre um campo de entrada de texto:

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 personalizado para o campo de entrada de texto.

No Chrome no Windows, o campo de entrada de texto fica sempre visível sem que você precise 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 é mostrado, da direita para a esquerda ou da esquerda para a direita.

Nos testes, parecia que a direção era amplamente determinada pelo texto, e não por esse parâmetro. De acordo com a especificação, o objetivo é sugerir ao navegador como definir opções como ações, mas não notei diferença.

É melhor definir se você puder. Caso contrário, o navegador fará a coisa certa de acordo com o texto fornecido.

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

Um idioma da direita para a esquerda usado no Chrome no Linux fica assim:

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

No Firefox (ao passar o cursor sobre ele), você vai ver isto:

Notificação com idioma 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 descreva o número de milissegundos em que o dispositivo precisa vibrar, seguido pelo número de milissegundos em que o dispositivo não precisa 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 afeta apenas dispositivos compatíveis com vibração.

Som

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

No momento da redação deste artigo, 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

Com o carimbo de data/hora, você informa à plataforma a hora 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, ou seja, 1º de janeiro de 1970, que é a época do 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

O maior fracasso de UX que vi com notificações é a falta de especificidade nas informações exibidas por uma notificação.

Você precisa considerar por que enviou a mensagem push e garantir que todas as opções de notificação sejam usadas para ajudar os usuários a entender por que eles estão lendo essa notificação.

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

Evite estas armadilhas comuns:

  • Não coloque seu site no título ou no corpo. Os navegadores incluem seu domínio na notificação. Não duplique o domínio.
  • 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 um título de "Nova mensagem" e o corpo de "Clique aqui para ler", use um título de "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, há uma grande disparidade entre o Chrome e o Firefox em termos de suporte a recursos para notificações.

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

Digamos que você queira saber se uma notificação oferece suporte a botões de ação. Para isso, faça 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.

Para as outras opções, faça o mesmo que acima, substituindo 'actions' pelo nome do parâmetro desejado.

A seguir

Codelabs