social

Manifest de aplicación web

MetricSpot comprueba que haya un web app manifest enlazado. Es obligatorio para los prompts de instalación en Android, el icono de la tab strip y la PWA moderna en Chromium.

Qué comprueba esta verificación

Busca <link rel="manifest" href="..."> en el head del documento, descarga el archivo JSON referenciado y valida que parsea y contiene los campos que los navegadores necesitan para mostrar un prompt de instalación: name (o short_name), start_url, icons con al menos un 192×192 y un 512×512, y display.

Por qué importa

El manifest controla cómo trata el sistema operativo a tu sitio una vez que el usuario lo añade a su pantalla de inicio.

  • Android (Chrome, Samsung Internet, Edge): con un manifest válido más un service worker, el navegador muestra el prompt “Añadir a pantalla de inicio”. Sin él, no aparece el banner de instalación — los usuarios tienen que encontrar la opción oculta del menú.
  • Chromebook / Chrome y Edge en escritorio: instalable como app independiente desde el icono de la omnibox.
  • Safari en iOS: lee name, theme_color y apple-touch-icon (que sigue siendo un link aparte). No respeta display: standalone del manifest — también necesitas <meta name="apple-mobile-web-app-capable" content="yes">.
  • Tab strip: Chrome usa theme_color del manifest (y de la meta tag correspondiente) como color de fondo de la barra de direcciones.

Aunque no quieras un prompt de instalación PWA, el manifest sigue alimentando el favicon que usa Android cuando los usuarios añaden un marcador, y el icono que Chrome muestra en el menú overflow de pestañas en móvil.

Cómo arreglarlo

1. Enlaza el manifest desde cada página:

<link rel="manifest" href="/manifest.webmanifest" />
<meta name="theme-color" content="#0b0b0b" />
<link rel="apple-touch-icon" href="/apple-touch-icon.png" />

La extensión convencional es .webmanifest, pero .json también funciona siempre que la respuesta se sirva con Content-Type: application/manifest+json (o application/json).

2. Escribe un manifest mínimo válido:

{
  "name": "MetricSpot",
  "short_name": "MetricSpot",
  "start_url": "/",
  "scope": "/",
  "display": "standalone",
  "background_color": "#ffffff",
  "theme_color": "#0b0b0b",
  "icons": [
    {
      "src": "/icons/icon-192.png",
      "sizes": "192x192",
      "type": "image/png",
      "purpose": "any"
    },
    {
      "src": "/icons/icon-512.png",
      "sizes": "512x512",
      "type": "image/png",
      "purpose": "any"
    },
    {
      "src": "/icons/maskable-512.png",
      "sizes": "512x512",
      "type": "image/png",
      "purpose": "maskable"
    }
  ]
}

El icono maskable es el que Android usa para la insignia de la pantalla de inicio. Sin él, Android recorta tu icono y te queda un círculo de espacio en blanco alrededor del logo. Pruébalo con maskable.app.

3. Sirve el content type correcto:

location = /manifest.webmanifest {
  default_type application/manifest+json;
  add_header Cache-Control "public, max-age=3600";
}

Si tu host lo sirve como text/plain o text/html, Chrome ignora el archivo en silencio.

Astro: mete manifest.webmanifest en public/ — Astro lo copia a la raíz del sitio sin modificar. Añade el <link> a tu layout base.

Next.js (App Router): exporta un manifest tipado desde app/manifest.ts y Next emite el JSON en build time:

// app/manifest.ts
import type { MetadataRoute } from "next";

export default function manifest(): MetadataRoute.Manifest {
  return {
    name: "MetricSpot",
    short_name: "MetricSpot",
    start_url: "/",
    display: "standalone",
    background_color: "#ffffff",
    theme_color: "#0b0b0b",
    icons: [
      { src: "/icons/icon-192.png", sizes: "192x192", type: "image/png" },
      { src: "/icons/icon-512.png", sizes: "512x512", type: "image/png" },
    ],
  };
}

El <link rel="manifest"> lo inyecta Next automáticamente cuando existe este archivo.

WordPress: lo más simple es un plugin PWA (PWA by 10up, o Super Progressive Web Apps). O escribes el manifest tú, lo dejas en la raíz del tema y añades la etiqueta <link> vía wp_head:

add_action('wp_head', function () {
  echo '<link rel="manifest" href="' . esc_url(get_template_directory_uri() . '/manifest.webmanifest') . '">';
});

4. Combínalo con las meta tags adecuadas. El manifest hace casi todo el trabajo, pero Safari en iOS y los rastreadores antiguos siguen queriendo las etiquetas por separado:

<meta name="theme-color" content="#0b0b0b" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
<link rel="apple-touch-icon" href="/apple-touch-icon.png" />

Mira también Apple touch icon y Favicon para el resto del set de iconos.

Preguntas frecuentes

¿Necesito un service worker para pasar esta verificación?

No. La verificación del manifest sólo comprueba el <link> y el archivo JSON. Necesitas un service worker para que la app sea instalable como PWA en Android — sin él, el prompt de instalación no aparece ni con un manifest perfecto. El manifest sólo ya te da un mejor icono en pantalla de inicio y metadatos de tab strip.

¿Por qué no aparece el prompt de instalación en Android?

Hacen falta tres cosas: un manifest válido con iconos 192×192 y 512×512, un service worker que maneje eventos fetch, y el sitio servido por HTTPS. Mira chrome://inspect → “Devices” → tu pestaña → Application → Manifest en DevTools — Chrome lista exactamente qué criterios de instalación faltan.

¿Cuál es la diferencia entre display: standalone y display: fullscreen?

standalone esconde el chrome del navegador pero mantiene la barra de estado del sistema (notificaciones, hora, batería) — lo que casi todas las apps quieren. fullscreen esconde todo y suele ser apropiado sólo para juegos. minimal-ui mantiene una barra fina con atrás/adelante; se usa raramente. La mayoría de apps instalables quieren standalone.

Fuentes

Última actualización 2026-05-11