social

Web app manifest

O MetricSpot verifica se há um web app manifest ligado. É necessário para os prompts de instalação no Android, o ícone na barra de separadores e o comportamento PWA moderno.

O que esta verificação faz

Procura <link rel="manifest" href="..."> no head do documento, vai buscar o ficheiro JSON referenciado e valida que faz parse e contém os campos que os navegadores exigem para mostrar um prompt de instalação: name (ou short_name), start_url, icons com pelo menos um 192×192 e um 512×512, e display.

Porque é importante

O manifest controla como o sistema operativo trata o teu site depois de um utilizador o adicionar ao ecrã principal.

  • Android (Chrome, Samsung Internet, Edge): com um manifest válido mais um service worker, o navegador mostra o prompt “Adicionar ao ecrã principal”. Sem isto, não há banner de instalação — os utilizadores têm de encontrar a opção escondida no menu.
  • Chromebook / Chrome de desktop / Edge: instalável como aplicação independente a partir do ícone na omnibox da barra de endereços.
  • iOS Safari:name, theme_color e apple-touch-icon (ainda um link separado). Não honra display: standalone do manifest — também precisas de <meta name="apple-mobile-web-app-capable" content="yes">.
  • Barra de separadores: o Chrome usa o theme_color do manifest (e da meta tag correspondente) para a cor de fundo da barra de endereços.

Mesmo que não queiras um prompt de instalação PWA, o manifest continua a alimentar o favicon que o Android usa quando os utilizadores adicionam um marcador, e o ícone que o Chrome mostra no menu overflow de separadores no telemóvel.

Como corrigir

1. Liga o manifest a partir de todas as páginas:

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

Por convenção a extensão é .webmanifest, mas .json também funciona desde que a resposta seja servida com Content-Type: application/manifest+json (ou application/json).

2. Escreve um 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"
    }
  ]
}

O ícone maskable é o que o Android usa para o badge no ecrã principal. Sem ele, o Android recorta o teu ícone e ficas com um círculo de espaço branco à volta de um logótipo. Testa com maskable.app.

3. Serve o content type correto:

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

Se o teu host o servir como text/plain ou text/html, o Chrome ignora o ficheiro silenciosamente.

Astro: coloca manifest.webmanifest em public/ — o Astro copia-o para a raiz do site sem alterações. Adiciona o <link> ao teu layout base.

Next.js (App Router): exporta um manifest tipado a partir de app/manifest.ts e o Next emite o JSON em tempo de build:

// 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" },
    ],
  };
}

O <link rel="manifest"> é injetado automaticamente pelo Next quando este ficheiro existe.

WordPress: o caminho mais simples é um plugin de PWA (PWA by 10up, ou Super Progressive Web Apps). Ou escreves o manifest tu, colocas na raiz do tema e adicionas a tag <link> via wp_head:

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

4. Combina com as meta tags certas. O manifest faz quase todo o trabalho, mas o iOS Safari e os crawlers legacy ainda querem as tags separadas:

<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" />

Vê também Apple touch icon e Favicon para o resto do conjunto de ícones.

Perguntas frequentes

Preciso de um service worker para passar esta verificação?

Não. A verificação do manifest só valida o <link> e o ficheiro JSON. Precisas de um service worker para ser instalável como PWA no Android — sem ele, o prompt de instalação não aparece mesmo com um manifest perfeito. O manifest sozinho ainda te dá um melhor ícone no ecrã principal e metadados de barra de separadores.

Porque é que o meu prompt de instalação não aparece no Android?

São necessárias três coisas: um manifest válido com ícones 192×192 e 512×512, um service worker que trata eventos fetch, e o site servido em HTTPS. Verifica em chrome://inspect → “Devices” → o teu separador → Application → Manifest no DevTools — o Chrome lista exatamente que critérios de instalação estão em falta.

Qual é a diferença entre display: standalone e display: fullscreen?

standalone esconde o chrome do navegador mas mantém a barra de estado do SO (notificações, hora, bateria) — o que a maioria das apps quer. fullscreen esconde tudo e geralmente só é apropriado para jogos. minimal-ui mantém uma barra fina do navegador com retroceder/avançar; raramente usada. A maioria das apps instaláveis quer standalone.

Fontes

Última atualização 2026-05-11