<head>, Meta Tags, and Document Security
The <head> configures rendering, SEO, social sharing, and security. Know the essential meta tags (charset, viewport, theme-color, referrer policy), how Open Graph/Twitter cards drive link previews, how JSON-LD structured data feeds rich search results, and the security-relevant attributes: CSP (best via HTTP header, possible via <meta>), SRI (integrity) for third-party scripts, crossorigin, and nonce for inline-script allowlisting. The frontend angle on security is mostly here and in Frontend Security — Senior Interview Prep.
Which meta tags are non-negotiable?
<meta charset="utf-8" /> <!-- first; encoding -->
<meta name="viewport" content="width=device-width, initial-scale=1" /> <!-- responsive -->
<title>Page title</title> <!-- SEO + tab + a11y -->
<meta name="description" content="…" /> <!-- search snippet -->
<meta name="theme-color" content="#0b0b0b" /> <!-- browser UI tint -->charset must be in the first 1024 bytes. viewport is mandatory for mobile. theme-color (with media for light/dark) tints the mobile browser chrome. viewport-fit=cover handles notches/safe areas.
How do Open Graph and Twitter cards work?
Meta tags read by social platforms/crawlers to build link previews:
<meta property="og:title" content="…" />
<meta property="og:description" content="…" />
<meta property="og:image" content="https://…/preview.png" />
<meta property="og:type" content="website" />
<meta name="twitter:card" content="summary_large_image" />They must be server-rendered — most crawlers don’t run JS, so a pure CSR SPA shows no preview. This is a concrete reason to SSR/prerender (Rendering Modes — Senior Interview Prep). og:image should be an absolute URL.
What is JSON-LD and why use it over microdata?
JSON-LD is structured data (schema.org) in a <script type="application/ld+json"> block — it tells search engines what the page is (Article, Product, FAQ, BreadcrumbList) to enable rich results:
<script type="application/ld+json">
{ "@context": "https://schema.org", "@type": "Product", "name": "…", "offers": { "@type": "Offer", "price": "29.00" } }
</script>Preferred over inline microdata/RDFa because it’s decoupled from the markup (one block, no attribute clutter) and Google recommends it.
How do you set a Content Security Policy, and meta vs header?
CSP restricts where resources can load from, mitigating XSS. Prefer the HTTP header (Content-Security-Policy) — it supports the full feature set including frame-ancestors and reporting. The <meta http-equiv="Content-Security-Policy"> form works for some directives but can’t use frame-ancestors/report-uri and applies only after parsing begins.
<meta http-equiv="Content-Security-Policy"
content="default-src 'self'; script-src 'self' 'nonce-abc123'; img-src 'self' data:;" />Full CSP treatment: Frontend Security — Senior Interview Prep.
What are SRI, crossorigin, and nonce?
- SRI (
integrity) — a hash that the browser verifies before executing a third-party script/style; if the CDN file was tampered with, it’s blocked. Requirescrossorigin:<script src="https://cdn.example/lib.js" integrity="sha384-…" crossorigin="anonymous"></script> crossorigin— controls CORS mode for the request (anonymous= no credentials); needed for SRI and for readable cross-origin errors/fonts.nonce— a per-response random token; CSP allows only inline scripts carrying the matchingnonce, so injected inline scripts (XSS) are blocked. The nonce must be unique per response and never reused.
What does the referrer policy control?
<meta name="referrer" content="strict-origin-when-cross-origin"> (or the referrerpolicy attribute / header) controls how much of the URL is sent in the Referer header on outbound requests — a privacy/leak control (don’t leak query strings/paths to third parties). strict-origin-when-cross-origin is a sane default (full URL same-origin, only origin cross-origin, nothing on downgrade).
Gotchas
og:/Twitter tags in a CSR SPA don’t work — crawlers see the empty shell. SSR/prerender for shareable pages.- CSP via
<meta>is limited — noframe-ancestors, noreport-uri, and it can’t protect resources requested before the meta tag is parsed; use the header for real security. - SRI without
crossoriginsilently fails (the resource loads but integrity isn’t enforced, or it’s blocked) — always pair them. - Reused/predictable nonces defeat the purpose — generate per request, server-side.
theme-colorignored on some browsers/desktop — progressive enhancement, not guaranteed.- Duplicate/oversized
og:image— platforms cache previews aggressively; changing the image may need a re-scrape. - Missing
charsetearly can cause a re-parse or mojibake — put it first.
Related
Further reading
- MDN —
<meta>: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/meta - MDN — Subresource Integrity: https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity
- Open Graph protocol: https://ogp.me/
- schema.org / Google structured data: https://developers.google.com/search/docs/appearance/structured-data
Interview angle 6
- “What belongs at the top of
<head>, and in what order?” -charsetfirst, because the parser must know the encoding before it decodes anything else, thenviewportso mobile layout is correct from the first paint.theme-colorand the rest can follow. - “Your Open Graph card is blank when the link is shared.” - the tags are being added by client-side JavaScript and crawlers do not run it. OG and Twitter tags must be in the server-rendered HTML, which is a concrete reason to SSR any page meant to be shared.
- “Structured data: JSON-LD or microdata?” - JSON-LD. It sits in one script block, decoupled from the markup, so changing the layout cannot break the schema. Microdata interleaves the two and is what breaks silently.
- “Can you set a CSP in a
<meta>tag?” - partly, and not the parts that matter most.frame-ancestorsand reporting directives are ignored in meta, so clickjacking protection and any visibility into violations require the HTTP header.- Follow-up: “How do you keep your own inline scripts working under CSP?” -
a per-response
nonceon the tags you control. An injected script has no nonce, so it is blocked while yours runs, which is the whole point.
- Follow-up: “How do you keep your own inline scripts working under CSP?” -
a per-response
- “What does Subresource Integrity actually protect against?” - a
third-party host serving different bytes than the ones you reviewed, whether
through a compromise or a silent version bump. The hash pins the content, and
it needs
crossoriginor the browser cannot read the response to check it. - “Why set a referrer policy?” - because the full URL, including path and query, is sent to every third party you load a resource from. A tighter policy stops internal paths and identifiers in query strings leaking to analytics and CDNs by default.