JSONLD MIME Type – Free, Online, Private
application/ld+json is the type for a JSON-LD document. A script tag of that type inside HTML is data, not JavaScript.
What .jsonld is
JSON-LD is JSON with a linked-data context. The @context member maps terms onto IRIs. The document can say things search engines and other processors extract, which is why sites embed it in a script type=application/ld+json element. That script is not executed as JavaScript. The type on the script element is what stops execution. A standalone .jsonld file served over HTTP uses the same type, application/ld+json. The body is UTF-8. Do not add a charset parameter. application/json is a valid fallback only for a client that does not care about the context. A processor that understands JSON-LD looks for application/ld+json.
IANA registers application/ld+json for JSON-LD. The media type is application/ld+json. Extensions that use it on this page: .jsonld. 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/ld+json
What sends application/ld+json: Send application/ld+json for a .jsonld document and for an API that returns a compacted or expanded document. If the JSON-LD is embedded in HTML, the page's type is text/html and the script element carries application/ld+json. Do not serve the whole page as application/ld+json. When you negotiate between HTML and JSON-LD on one URL, send Vary: Accept. A context URL fetched by a processor is a separate request. If that context is itself JSON-LD, it uses this type. If it is a plain JSON object some publishers host, application/json is what those files often are. Be consistent on your own host. The file on disk is still .jsonld. Once the response exists, a client trusts application/ld+json, not the filename. Structured data for search engines is only useful if the values match the visible page. The type can be perfect and the markup can still be spam if the name and the price disagree with the HTML. Fix the content. Do not serve a second, hidden JSON-LD document from a .jsonld URL and expect it to override the page.
Content-Type for .jsonld
Send application/ld+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/ld+json
nginx, Apache, and Express
These snippets map .jsonld to application/ld+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 .jsonld 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/ld+json jsonld;
ApacheAddType application/ld+json .jsonld
Expressimport express from "express";
const app = express();
app.use(express.static("public", {
setHeaders(res, filePath) {
if (filePath.endsWith(".jsonld")) {
res.setHeader("Content-Type", "application/ld+json");
}
},
}));
Pitfalls for application/ld+json
Pitfalls that show up for application/ld+json, and not for a neighboring type with a similar extension: The XSS trap is a JSON-LD script that contains a string with </script> in it, which closes the HTML element early. Escape that sequence when you embed the document. The media type does not escape it. Another trap is a remote @context that a processor fetches on every request, which leaks the fetch to that host and fails closed when the host is down. Pin or inline the context if you need the page to process offline. A third is sending application/ld+json for JSON that has no context and no linked-data shape. Use application/json. A fourth is a compacted document and an expanded document cached as the same URL.
- A script type=application/ld+json does not run as a script. type=text/javascript would. Do not mix them up to 'make it dynamic'.
- application/ld+json is not application/json. Clients that switch on the full type need the ld token.
- The @graph member is still this type. Multiple nodes do not require multiple responses.
- Do not put a BOM in front of the brace.
Frequently asked questions
Does a JSON-LD script execute?
No. In HTML, script type=application/ld+json is data. The browser does not run it as JavaScript.
Is application/json acceptable?
A JSON parser will read the body. A JSON-LD processor looks for application/ld+json. Send the specific type.
Should I add charset=utf-8?
No. Omit the charset parameter. The document is UTF-8 JSON.
What is @context for?
It maps the terms in the document to IRIs. Without it a processor cannot expand the terms, even if the Content-Type is correct.