Cómo mostrar una notificación

Las opciones de notificaciones se dividen en dos secciones: una que se ocupa de los aspectos visuales (esta sección) y otra que explica los aspectos conductuales de las notificaciones (la siguiente sección).

Puedes probar varias opciones de notificaciones en diferentes navegadores y plataformas con el Notification Generator de Peter Beverloo.

Opciones visuales

La API para mostrar una notificación es simple:

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

Ambos argumentos, title y options, son opcionales.

El título es una cadena, y las opciones pueden ser cualquiera de las siguientes:

{
  "//": "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>",
}

Veamos las opciones visuales:

Disección de la IU de una notificación.

Opciones de título y cuerpo

Así se ve una notificación sin el título ni las opciones en Chrome para Windows:

Notificación sin el título ni las opciones en Chrome para Windows.

Como puedes ver, el nombre del navegador se usa como título y el marcador de posición "Nueva notificación" se usa como cuerpo de la notificación.

Si hay una aplicación web progresiva instalada en el dispositivo, se usará el nombre de la app web en lugar del nombre del navegador:

Notificación con el nombre de la app web en lugar del nombre del navegador.

Si ejecutáramos el siguiente código:

const title = 'Simple Title';

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

registration.showNotification(title, options);

recibiríamos esta notificación en Chrome para Linux:

Notificación con título y texto del cuerpo en Chrome para Linux.

En Firefox para Linux, se vería de la siguiente manera:

Notificación con título y texto del cuerpo en Firefox para Linux.

Así se ve la notificación con mucho texto en el título y el cuerpo en Chrome en Linux:

Notificación con título y cuerpo de texto largos en Chrome para Linux.

Firefox para Linux contrae el texto del cuerpo hasta que colocas el cursor sobre la notificación, lo que hace que esta se expanda:

Notificación con título y texto del cuerpo largos en Firefox para Linux.

Notificación con título y texto del cuerpo largos en Firefox para Linux cuando se coloca el cursor del mouse sobre ella.

Las mismas notificaciones en Firefox para Windows se ven de la siguiente manera:

Notificación con título y texto del cuerpo en Firefox para Windows.

Notificación con título y texto del cuerpo largos en Firefox para Windows.

Como puedes ver, la misma notificación puede verse diferente en diferentes navegadores. También puede verse diferente en el mismo navegador en diferentes plataformas.

Chrome y Firefox usan las notificaciones del sistema y el centro de notificaciones en las plataformas donde están disponibles.

Por ejemplo, las notificaciones del sistema en macOS no admiten imágenes ni acciones (botones y respuestas intercaladas).

Chrome también tiene notificaciones personalizadas para todas las plataformas de escritorio. Para habilitarlo, configura la marca chrome://flags/#enable-system-notifications en el estado Disabled.

Ícono

La opción icon es, en esencia, una imagen pequeña que puedes mostrar junto al título y el texto del cuerpo.

En tu código, debes proporcionar una URL a la imagen que deseas cargar:

const title = 'Icon Notification';

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

registration.showNotification(title, options);

Recibirás esta notificación en Chrome para Linux:

Notificación con ícono en Chrome para Linux.

y en Firefox para Linux:

Notificación con ícono en Firefox en Linux.

Lamentablemente, no hay lineamientos sólidos sobre el tamaño de la imagen que se debe usar para un ícono.

Al parecer, Android requiere una imagen de 64 dp (que es un múltiplo de 64 px por la relación de píxeles del dispositivo).

Si suponemos que la proporción de píxeles más alta de un dispositivo es 3, un tamaño de ícono de 192 px o más es una opción segura.

Insignia

badge es un ícono monocromático pequeño que se usa para mostrarle al usuario un poco más de información sobre el origen de la notificación:

const title = 'Badge Notification';

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

registration.showNotification(title, options);

En el momento de escribir este artículo, la insignia solo se usa en Chrome para Android.

Notificación con insignia en Chrome para Android.

En otros navegadores (o Chrome sin la insignia), verás el ícono del navegador.

Notificación con insignia en Firefox para Android.

Al igual que con la opción icon, no hay lineamientos reales sobre qué tamaño usar.

Según los lineamientos de Android, el tamaño recomendado es de 24 px multiplicado por la relación de píxeles del dispositivo.

Es decir, una imagen de 72 px o más debería ser adecuada (suponiendo una proporción de píxeles máxima del dispositivo de 3).

Imagen

La opción image se puede usar para mostrarle al usuario una imagen más grande. Esto es útil, en particular, para mostrarle al usuario una imagen de vista previa.

const title = 'Image Notification';

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

registration.showNotification(title, options);

En Chrome para Linux, la notificación se verá de la siguiente manera:

Notificación con imagen en Chrome para Linux.

En Chrome para Android, el recorte y la relación son diferentes:

Notificación con imagen en Chrome para Android.

Debido a las diferencias en la proporción entre computadoras de escritorio y dispositivos móviles, es muy difícil sugerir lineamientos.

Dado que Chrome para computadoras de escritorio no ocupa el espacio disponible y tiene una relación de 4:3, quizás el mejor enfoque sea publicar una imagen con esta relación y permitir que Android la recorte. Dicho esto, la opción image aún puede cambiar.

En Android, la única directiva es un ancho de 450 dp.

Según este criterio, una imagen de 1,350 px de ancho o más sería una buena opción.

Acciones (botones)

Puedes definir actions para mostrar botones con una notificación:

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 acción, puedes definir un title, un action (que es esencialmente un ID), un icon y un type. El título y el ícono son lo que puedes ver en la notificación. El ID se usa cuando se detecta que se hizo clic en el botón de acción (obtén más información sobre esto en la siguiente sección). Se puede omitir el tipo porque 'button' es el valor predeterminado.

En el momento de escribir este artículo, solo Chrome y Opera para Android admiten acciones.

En el ejemplo anterior, se definen cuatro acciones para ilustrar que puedes definir más acciones que las que se mostrarán. Si quieres conocer la cantidad de acciones que mostrará el navegador, puedes consultar 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.';
}

En computadoras, los íconos de los botones de acción muestran sus colores (consulta el donut rosa):

Notificación con botones de acción en Chrome para Linux.

En Android 6 y versiones anteriores, los íconos tienen el color del esquema de colores del sistema:

Notificación con botones de acción en Chrome para Android.

En Android 7 y versiones posteriores, los íconos de acción no se muestran en absoluto.

Con suerte, Chrome cambiará su comportamiento en computadoras de escritorio para que coincida con Android (es decir, aplicará el esquema de colores adecuado para que los íconos coincidan con el aspecto del sistema). Mientras tanto, puedes hacer que tus íconos tengan el color #333333 para que coincidan con el color del texto de Chrome.

También vale la pena señalar que los íconos se ven nítidos en Android, pero no en computadoras.

El mejor tamaño que pude hacer funcionar en Chrome para computadoras de escritorio fue de 24 px x 24 px. Lamentablemente, esto se ve fuera de lugar en Android.

La práctica recomendada que podemos extraer de estas diferencias es la siguiente:

  • Usa un esquema de colores coherente para los íconos, de modo que, al menos, todos se muestren de manera coherente al usuario.
  • Asegúrate de que funcionen en monocromo, ya que algunas plataformas pueden mostrarlos de esa manera.
  • Prueba el tamaño y descubre qué funciona para ti. 128 px × 128 px funciona bien en Android, pero tiene una calidad deficiente en computadoras.
  • Es posible que tus íconos de acción no se muestren.

La especificación de notificaciones está explorando una forma de definir varios tamaños de íconos, pero parece que pasará un tiempo antes de que se llegue a un acuerdo.

Acciones (respuestas intercaladas)

Para agregar una respuesta intercalada a la notificación, define una acción con el 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);

Así se verá en Android:

Notificación en Android con un botón de acción de respuesta.

Cuando haces clic en el botón de acción, se abre un campo de entrada de texto:

Notificación en Android con un campo de entrada de texto abierto.

Puedes personalizar el marcador de posición para el 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);

Notificación en Android con marcador de posición personalizado para el campo de entrada de texto.

En Chrome para Windows, el campo de entrada de texto siempre está visible sin tener que hacer clic en el botón de acción:

Notificación en Windows con un campo de entrada de texto y un botón de acción de respuesta.

Puedes agregar más de una respuesta intercalada o combinar botones y respuestas intercaladas:

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);

Notificación en Windows con un campo de entrada de texto y dos botones de acción.

Dirección

El parámetro dir te permite definir en qué dirección se debe mostrar el texto, de derecha a izquierda o de izquierda a derecha.

En las pruebas, parecía que la dirección estaba determinada en gran medida por el texto en lugar de este parámetro. Según la especificación, el objetivo es sugerirle al navegador cómo diseñar opciones como las acciones, pero no vi ninguna diferencia.

Lo mejor es definirlo si puedes. De lo contrario, el navegador debería hacer lo correcto según el texto proporcionado.

El parámetro debe establecerse en auto, ltr o rtl.

Un idioma de derecha a izquierda que se usa en Chrome en Linux se ve de la siguiente manera:

Notificación con idioma de derecha a izquierda en Chrome para Linux.

En Firefox (cuando colocas el cursor sobre él), verás lo siguiente:

Notificación con idioma de derecha a izquierda en Firefox para Linux.

Vibrar

La opción de vibración te permite definir un patrón de vibración que se ejecutará cuando se muestre una notificación, siempre que la configuración actual del usuario permita las vibraciones (es decir, que el dispositivo no esté en modo silencioso).

El formato de la opción de vibración debe ser un array de números que describan la cantidad de milisegundos que el dispositivo debe vibrar, seguida de la cantidad de milisegundos que el dispositivo no debe 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);

Esto solo afecta a los dispositivos que admiten vibración.

Sonido

El parámetro sound te permite definir un sonido para que se reproduzca cuando se reciba la notificación.

En el momento de escribir este artículo, ningún navegador admite esta opción.

const title = 'Sound Notification';

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

registration.showNotification(title, options);

Marca de tiempo

La marca de tiempo te permite indicarle a la plataforma la hora en que ocurrió un evento que generó el envío de la notificación push.

timestamp debe ser la cantidad de milisegundos desde las 00:00:00 UTC, que corresponde al 1 de enero de 1970 (la época de 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ácticas recomendadas de UX

El mayor error de UX que he visto con las notificaciones es la falta de especificidad en la información que muestra una notificación.

En primer lugar, debes considerar por qué enviaste el mensaje push y asegurarte de que se usen todas las opciones de notificación para ayudar a los usuarios a comprender por qué están leyendo esa notificación.

Honestamente, es fácil ver ejemplos y pensar "Nunca cometeré ese error". Sin embargo, es más fácil caer en esa trampa de lo que crees.

Estos son algunos de los errores comunes que debes evitar:

  • No incluyas tu sitio web en el título ni en el cuerpo. Los navegadores incluyen tu dominio en la notificación, por lo que no lo duplican.
  • Usa toda la información que tengas disponible. Si envías un mensaje push porque alguien envió un mensaje a un usuario, en lugar de usar un título de "Mensaje nuevo" y un cuerpo de "Haz clic aquí para leerlo", usa un título de "Juan acaba de enviar un mensaje nuevo" y establece el cuerpo de la notificación como parte del mensaje.

Navegadores y detección de funciones

En el momento de escribir este artículo, hay una gran disparidad entre Chrome y Firefox en términos de compatibilidad con funciones para notificaciones.

Por suerte, puedes detectar la compatibilidad con las funciones de notificación si observas el prototipo de window.Notification.

Supongamos que queremos saber si una notificación admite botones de acción. Para ello, haríamos lo siguiente:

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

Con esto, podríamos cambiar la notificación que mostramos a nuestros usuarios.

Con las otras opciones, haz lo mismo que antes y reemplaza 'actions' por el nombre del parámetro deseado.

Próximos pasos

Code labs