social
Web app manifest
MetricSpot checks for a linked web app manifest. It's required for Android install prompts, the tab-strip icon, and modern PWA behavior across Chromium browsers.
What this check does
Looks for <link rel="manifest" href="..."> in the document head, fetches the referenced JSON file, and validates that it parses and contains the fields browsers require to show an install prompt: name (or short_name), start_url, icons with at least one 192×192 and one 512×512, and display.
Why it matters
The manifest controls how the operating system treats your site once a user adds it to their home screen.
- Android (Chrome, Samsung Internet, Edge): with a valid manifest plus a service worker, the browser shows the “Add to Home Screen” prompt. Without it, no install banner — users have to find the hidden menu option.
- Chromebook / desktop Chrome / Edge: installable as a standalone app from the address bar omnibox icon.
- iOS Safari: reads
name,theme_color, andapple-touch-icon(still a separate link). Doesn’t honordisplay: standalonefrom the manifest — you also need<meta name="apple-mobile-web-app-capable" content="yes">. - Tab strip: Chrome uses
theme_colorfrom the manifest (and the matching meta tag) for the address-bar background color.
Even if you don’t want a PWA install prompt, the manifest still feeds the favicon used by Android when users add a bookmark, and the icon Chrome shows in the tab overflow menu on mobile.
How to fix it
1. Link the manifest from every page:
<link rel="manifest" href="/manifest.webmanifest" />
<meta name="theme-color" content="#0b0b0b" />
<link rel="apple-touch-icon" href="/apple-touch-icon.png" />
The file extension is conventionally .webmanifest, but .json works too as long as the response is served with Content-Type: application/manifest+json (or application/json).
2. Write a minimal valid manifest:
{
"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"
}
]
}
The maskable icon is the one Android uses for the home-screen badge. Without it, Android crops your icon and you get a circle of white space around a logo. Test with maskable.app.
3. Serve the right content type:
location = /manifest.webmanifest {
default_type application/manifest+json;
add_header Cache-Control "public, max-age=3600";
}
If your host serves it as text/plain or text/html, Chrome ignores the file silently.
Astro: drop manifest.webmanifest into public/ — Astro copies it to the site root unchanged. Add the <link> to your base layout.
Next.js (App Router): export a typed manifest from app/manifest.ts and Next emits the JSON at 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" },
],
};
}
The <link rel="manifest"> is injected automatically by Next when this file exists.
WordPress: the simplest path is a PWA plugin (PWA by 10up, or Super Progressive Web Apps). Or write the manifest yourself, drop it in the theme’s root, and add the <link> tag via wp_head:
add_action('wp_head', function () {
echo '<link rel="manifest" href="' . esc_url(get_template_directory_uri() . '/manifest.webmanifest') . '">';
});
4. Pair with the right meta tags. The manifest does most of the work, but iOS Safari and legacy crawlers still want the separate tags:
<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" />
See also Apple touch icon and Favicon for the rest of the icon set.
Frequently asked questions
Do I need a service worker to pass this check?
No. The manifest check only verifies the <link> and the JSON file. You need a service worker to be installable as a PWA on Android — without one, the install prompt won’t show even with a perfect manifest. The manifest alone still gives you a better home-screen icon and tab-strip metadata.
Why isn’t my install prompt showing on Android?
Three things are required: a valid manifest with 192×192 and 512×512 icons, a service worker that handles fetch events, and the site served over HTTPS. Check chrome://inspect → “Devices” → your tab → Application → Manifest in DevTools — Chrome lists exactly which install criteria are missing.
What’s the difference between display: standalone and display: fullscreen?
standalone hides the browser chrome but keeps the OS status bar (notifications, time, battery) — what most apps want. fullscreen hides everything and is usually only appropriate for games. minimal-ui keeps a thin browser bar with back/forward; rarely used. Most installable apps want standalone.
Sources
Last updated 2026-05-11