
Next.js manifest.json
Every "Add to Home Screen" prompt, every PWA install banner, every app-like icon a browser shows for your site instead of just a generic bookmark — all of it traces back to one file: the Web App Manifest. Next.js treats it as a first-class file convention, supporting both a plain static JSON file and a fully code-generated variant, placed at the root of your app directory.
Static Manifest File
The simplest path is a literal file matching the Web Manifest Specification:
{
"name": "My Next.js Application",
"short_name": "Next.js App",
"description": "An application built with Next.js",
"start_url": "/"
}
Both manifest.json and manifest.webmanifest extensions are recognized — pick whichever your tooling or team convention prefers; Next.js treats them identically.
Generating a Manifest with Code
For cases where the manifest needs to vary — different theme colors per deployment environment, dynamically-generated icon lists — manifest.js or manifest.ts can export a default function returning a Manifest object instead of a static file:
import type { MetadataRoute } from "next";
export default function manifest(): MetadataRoute.Manifest {
return {
name: "Next.js App",
short_name: "Next.js App",
description: "Next.js App",
start_url: "/",
display: "standalone",
background_color: "#fff",
theme_color: "#fff",
icons: [
{
src: "/favicon.ico",
sizes: "any",
type: "image/x-icon",
},
],
};
}
Worth knowing about the underlying mechanics: manifest.js is, structurally, a special Route Handler, and like the other metadata-file Route Handlers, it's cached by default — unless the function itself reaches for a Request-time API or an explicit dynamic config option. For the overwhelming majority of manifests, which describe fixed, deployment-wide app metadata rather than anything genuinely request-specific, this default caching is exactly what you want with zero extra configuration.
The Manifest Object's Shape
The docs are deliberately non-exhaustive here, and for good reason: the Web Manifest Specification itself is an evolving web standard, with new fields periodically added as browser vendors extend what a manifest can describe. Rather than duplicating (and inevitably letting drift out of date) a full field-by-field reference, the recommended path is:
- If you're using TypeScript, let your editor's autocomplete on the
MetadataRoute.Manifesttype surface the current, accurate field list directly from Next.js's own type definitions. - Otherwise, the MDN Web Manifest documentation is the canonical, actively-maintained reference for what every field means and how browsers interpret it.
This is a deliberate design choice worth internalizing: for a spec this actively evolving, trusting the generated types (or MDN) over a static prose table is the more reliable approach — a hardcoded field list in any piece of documentation, including this one, risks going stale the moment the spec adds something new.
Key Takeaways
| Aspect | Detail |
|---|---|
| Location | Root of app directory |
| Static form | manifest.json or manifest.webmanifest |
| Dynamic form | manifest.js/manifest.ts, default-exporting a function returning MetadataRoute.Manifest |
| Caching | Cached by default, like other metadata-file Route Handlers, unless request-time data is used |
| Full field reference | Check the MetadataRoute.Manifest TypeScript type, or MDN's Web Manifest docs — not a fixed prose list |
A manifest file is small in scope but outsized in effect on how "real" your app feels once installed — the difference between a generic browser bookmark and something that looks and behaves like a native app icon on a user's home screen. Getting the file convention right is the easy part; the actual manifest content is worth spending real design attention on.


