Utilo

WEBMANIFEST MIME Type – Free, Online, Private

application/manifest+json is the type for a web app manifest. Browsers ignore a manifest served as a generic JSON type in some cases, and they always need this one to be safe.

What .webmanifest is

A web app manifest is a JSON document that describes a installable site: name, start URL, display mode, and icons. The extension the specification prefers is .webmanifest. The type is application/manifest+json. The body is UTF-8 JSON. Do not add a charset parameter. Icons listed inside the file are not this type. Each icon is fetched separately as image/png, image/svg+xml, or another image type. The manifest is the JSON. A link rel=manifest element in the HTML points at it. The HTML page stays text/html.

IANA registers application/manifest+json for the W3C web app manifest. The media type is application/manifest+json. Extensions that use it on this page: .webmanifest. A client compares the type, not the filename, once the response has arrived. The filename still matters on disk and in Content-Disposition, which is why a wrong extension and a wrong header are two different bugs.

What sends application/manifest+json

What sends application/manifest+json: Send application/manifest+json for the manifest URL. Many browsers also accept application/json. You should still send the specific type, because the specification says to and because a generic JSON type is easy to confuse with an API response in your logs and your CDN rules. Cache the manifest, and cache-bust it when the icon set or the start URL changes. A service worker does not replace the manifest. They are two different files with two different types. The worker script is text/javascript. The file on disk is still .webmanifest. Once the response exists, a client trusts application/manifest+json, not the filename. If the manifest is generated per user, mark it Cache-Control: private. A shared cache that stores one user's start_url for another user is a real bug and the media type will not prevent it. Public sites can cache a static manifest for a long time.

Content-Type for .webmanifest

Send application/manifest+json with no charset parameter. The registration either defines no charset parameter or tells clients to ignore one, and the payload is UTF-8 by rule rather than by a parameter. Adding charset=utf-8 looks helpful and has broken strict parsers.

Content-TypeContent-Type: application/manifest+json

nginx, Apache, and Express

These snippets map .webmanifest to application/manifest+json. nginx reads the types block when it picks a type from the URL's extension. A location that sets default_type, or an application that sets the header itself, overrides that map. Apache AddType applies in the directory context where you put it. The Express static example writes the header for files ending in .webmanifest so a stale mime database in the framework cannot disagree with the type on this page.

nginx# /etc/nginx/mime.types, inside the types { } block
application/manifest+json   webmanifest;
ApacheAddType application/manifest+json .webmanifest
Expressimport express from "express";

const app = express();
app.use(express.static("public", {
  setHeaders(res, filePath) {
    if (filePath.endsWith(".webmanifest")) {
      res.setHeader("Content-Type", "application/manifest+json");
    }
  },
}));

Pitfalls for application/manifest+json

Pitfalls that show up for application/manifest+json, and not for a neighboring type with a similar extension: The usual failure is a SPA fallback that returns index.html, as text/html, for /manifest.webmanifest. The browser rejects the manifest and the install prompt never appears. Exclude the manifest path from the fallback. Another failure is an icon URL that 404s. The manifest type can be perfect and the install still fails the image check. Another is a start_url that is cross-origin from the page. Browsers ignore it. Another is serving the manifest with a nosniff header and the wrong type, which removes any chance the browser will guess.

  • application/manifest+json is the registered type. application/x-web-app-manifest+json is an old unofficial value.
  • The file is JSON. Trailing commas and comments make the manifest invalid.
  • Icon files are images. Do not serve a PNG as application/manifest+json.
  • A BOM before the brace breaks JSON.parse. Start with { or [.

Frequently asked questions

Which Content-Type does a manifest need?

application/manifest+json. application/json is widely tolerated and is not the type the specification asks for.

Does the extension have to be .webmanifest?

It is the preferred extension. The browser decides based on the header and the JSON, but the extension is how your static server picks the header.

Should I send a charset?

No. Omit it. The manifest is UTF-8 JSON.

Why does install do nothing when the file looks right?

Often the response is actually index.html from a single-page fallback, or an icon URL in the manifest does not return an image.