Skip to content

Head

Head renders a full <head> element for a page by composing all metadata sub-components in a fixed order. Integration config provides defaults for most optional tags, while direct props take precedence for that render.

proptypedefaultrequireddescription
titlestring-YesRequired page title text. It is always rendered through Title.
descriptionstring-YesRequired <meta name="description"> content for the page.
titleTemplate`${string}%s${string}`integration configNoOptional %s template for title; when omitted, integration config is used, then "%s".
charsetstring | false"utf-8"NoCharacter set for <meta charset>. Pass false to suppress.
viewportstring | false"width=device-width, initial-scale=1"NoValue for <meta name="viewport">. Pass false to suppress.
baseComponentProps<typeof Base> | falseintegration configNoProps for <base>. Pass false to disable even when integration config provides it.
appleItunesAppComponentProps<typeof AppleItunesApp> | falseintegration configNoProps for the Apple Smart App Banner meta tag. Pass false to suppress.
extendComponentProps<typeof Extend>integration configNoAdditional link, meta, and custom tags inserted after the slot and before built-in tags that follow.
canonicalstring | URL | falsederived from Astro.siteNoCanonical URL rendered as <link rel="canonical">. Accepts string or URL. Pass false to suppress.
colorSchemestring | falseintegration configNoValue for <meta name="color-scheme">. Pass false to suppress.
generatorbooleantrueNoControls <meta name="generator">. Use false to suppress.
humansTxtstring | URL | falsederived from Astro.siteNoURL for <link rel="author" type="text/plain">. Accepts string or URL. Pass false to suppress.
iconsIconTag[] | falseintegration configNoOptional icon override array merged by href over integration icons. Pass false to suppress all icon links.
jsonLdstring-NoPre-serialized JSON-LD inserted as <script type="application/ld+json">. Omit to suppress.
languageAlternatesRecord<string, string | URL>-Nohreflang alternate links keyed by language code; values can be string or URL.
manifeststring | URL | falsederived from Astro.siteNoManifest URL rendered as <link rel="manifest">. Accepts string or URL. Pass false to suppress.
openGraphComponentProps<typeof OpenGraph>-NoOpen Graph metadata props. Omit to suppress all og:* tags.
robotsComponentProps<typeof Robots>integration configNoRobots directives object or explicit content string passed to Robots.
themeColorstring | { light: string; dark: string } | falseintegration configNoTheme color as either one string (content) or { light, dark } pair. Pass false to suppress.
verificationComponentProps<typeof Verification> | falseintegration configNoSearch-console verification token props. Pass false to suppress.

Input:

<Head title="Home" description="Home page" />

Output:

<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Home</title>
<meta name="description" content="Home page" />
<meta name="generator" content="Astro v6.1.1" />
</head>

Uses integration head.* defaults for omitted optional props.

Input:

// in astro.config.mjs integration config
eminence({
headTags: {
titleTemplate: "%s | My Site",
colorScheme: "dark",
},
});
<Head title="Home" description="Home page" />

Output:

<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Home | My Site</title>
<meta name="color-scheme" content="dark" />
<meta name="description" content="Home page" />
<meta name="generator" content="Astro v6.1.1" />
</head>

Input:

<Head
title="Home"
titleTemplate="%s | Example"
description="Welcome to Example"
base={{ href: "https://example.com", target: "_blank" }}
appleItunesApp={{ id: "1234567890", argument: "https://example.com/app" }}
canonical={new URL("https://example.com/")}
colorScheme="light dark"
humansTxt={new URL("https://example.com/humans.txt")}
manifest="https://example.com/manifest.webmanifest"
themeColor={{ light: "#ffffff", dark: "#111111" }}
openGraph={{
title: "Home",
url: "https://example.com/",
siteName: "Example",
}}
robots={{ content: "index, follow" }}
verification={{ google: "abc123" }}
icons={[
{
rel: "icon",
href: "https://example.com/icon.svg",
type: "image/svg+xml",
},
]}
jsonLd='{"@context":"https://schema.org","@type":"WebSite","name":"Example"}'
languageAlternates={{
en: "https://example.com/",
es: new URL("https://example.com/es/"),
}}
extend={{
link: [
{ rel: "preconnect", href: "https://cdn.example.com", prefetch: true },
],
meta: [{ property: "custom:token", content: "abc123" }],
custom: '<meta name="custom-inline" content="1">',
}}
/>

Output:

<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<base href="https://example.com" target="_blank" />
<title>Home | Example</title>
<link rel="preconnect" href="https://cdn.example.com" prefetch="true" />
<meta property="custom:token" content="abc123" />
<meta name="custom-inline" content="1" />
<meta
name="apple-itunes-app"
content="app-id=1234567890, app-argument=https://example.com/app"
/>
<link rel="canonical" href="https://example.com/" />
<meta name="color-scheme" content="light dark" />
<meta name="description" content="Welcome to Example" />
<meta name="generator" content="Astro v6.1.1" />
<link rel="author" href="https://example.com/humans.txt" type="text/plain" />
<link rel="icon" href="https://example.com/icon.svg" type="image/svg+xml" />
<script type="application/ld+json">
{ "@context": "https://schema.org", "@type": "WebSite", "name": "Example" }
</script>
<link rel="alternate" hreflang="en" href="https://example.com/" />
<link rel="alternate" hreflang="es" href="https://example.com/es/" />
<link rel="manifest" href="https://example.com/manifest.webmanifest" />
<meta property="og:type" content="website" />
<meta property="og:title" content="Home" />
<meta property="og:url" content="https://example.com/" />
<meta property="og:site_name" content="Example" />
<meta name="robots" content="index, follow" />
<meta
name="theme-color"
media="(prefers-color-scheme: light)"
content="#ffffff"
/>
<meta
name="theme-color"
media="(prefers-color-scheme: dark)"
content="#111111"
/>
<meta name="google-site-verification" content="abc123" />
</head>

title and description are intentionally required

Section titled “title and description are intentionally required”

Head always renders Title and Description, so both values are required at the component boundary to avoid accidental pages without core metadata.

Explicit false beats integration fallbacks

Section titled “Explicit false beats integration fallbacks”

For optional props that support false, passing false suppresses that tag even when integration config would otherwise produce output.

Fallback precedence is props then integration config

Section titled “Fallback precedence is props then integration config”

Child components that support integration defaults resolve values only when the relevant prop is omitted. Passing an object prop (including {}) marks that prop as provided and stops fallback for that child.

The default slot renders immediately after <title>, then extend tags are appended. Built-in tags that follow (appleItunesApp, canonical, description, and so on) are rendered afterward.

extend.custom uses set:html and is injected as-is. Only trusted or pre-sanitized content should be passed.

---
import type { ComponentProps } from "astro/types";
import {
AppleItunesApp,
Base,
Canonical,
Charset,
ColorScheme,
Description,
Extend,
Generator,
HumansTxt,
Icons,
JsonLd,
LanguageAlternates,
Manifest,
OpenGraph,
Robots,
ThemeColor,
Title,
Verification,
Viewport,
} from ".";
import type { ThemeColorValue } from "./ThemeColor.astro";
interface Props {
/**
* Character set for the document. Defaults to `"utf-8"`.
* Pass `false` to suppress the tag entirely.
*
* {@link https://eminence-astro-suite.xeffen25.com/components/charset Charset}
*/
charset?: ComponentProps<typeof Charset>["charset"] | false;
/**
* Viewport meta content value. Defaults to `"width=device-width, initial-scale=1"`.
* Pass `false` to suppress.
*
* {@link https://eminence-astro-suite.xeffen25.com/components/viewport Viewport}
*/
viewport?: ComponentProps<typeof Viewport>["content"] | false;
/**
* Props forwarded to the `Base` component for the `<base>` element.
* Falls back to integration config. Pass `false` to suppress the tag.
*
* {@link https://eminence-astro-suite.xeffen25.com/components/base Base}
*/
base?: ComponentProps<typeof Base> | false;
/**
* Required page title rendered inside `<title>`.
* Applied to `titleTemplate` when provided.
*
* {@link https://eminence-astro-suite.xeffen25.com/components/title Title}
*/
title: ComponentProps<typeof Title>["value"];
/**
* Template string with a `%s` placeholder substituted with `title` at render time.
* Falls back to integration config, then plain `%s` passthrough.
*
* {@link https://eminence-astro-suite.xeffen25.com/components/title Title}
*/
titleTemplate?: ComponentProps<typeof Title>["template"];
/**
* Props for the Apple iTunes Smart App Banner `<meta>` tag.
* Falls back to integration config. Pass `false` to suppress.
*
* {@link https://eminence-astro-suite.xeffen25.com/components/apple-itunes-app AppleItunesApp}
*/
appleItunesApp?: ComponentProps<typeof AppleItunesApp> | false;
/**
* Additional tags rendered after the component slot and before built-in tags.
* Prefer adding one-off tags directly inside the `Head` slot when possible.
*/
extend?: ComponentProps<typeof Extend>;
/**
* Canonical URL for the page rendered as `<link rel="canonical">`.
* Auto-derived from `Astro.site` when omitted. Pass `false` to suppress.
*
* {@link https://eminence-astro-suite.xeffen25.com/components/canonical Canonical}
*/
canonical?: ComponentProps<typeof Canonical>["href"] | false;
/**
* Color scheme hint rendered as `<meta name="color-scheme">`.
* Falls back to integration config. Pass `false` to suppress.
*
* {@link https://eminence-astro-suite.xeffen25.com/components/color-scheme ColorScheme}
*/
colorScheme?: ComponentProps<typeof ColorScheme>["content"] | false;
/**
* Page meta description rendered as `<meta name="description">`.
* Required for audits and SEO. Should be a concise summary of the page content.
*
* {@link https://eminence-astro-suite.xeffen25.com/components/description Description}
*/
description: ComponentProps<typeof Description>["content"];
/**
* Controls whether the `<meta name="generator">` tag is rendered.
* Defaults to `true`.
*
* {@link https://eminence-astro-suite.xeffen25.com/components/generator Generator}
*/
generator?: ComponentProps<typeof Generator>["generate"];
/**
* URL for the `humans.txt` discovery link.
* Auto-derived from `Astro.site` when omitted. Pass `false` to suppress.
*
* {@link https://eminence-astro-suite.xeffen25.com/components/humans-txt HumansTxt}
*/
humansTxt?: ComponentProps<typeof HumansTxt>["href"] | false;
/**
* Late-bound icon tags forwarded to the `Icons` component.
* Falls back to integration config. Pass `false` to suppress all icon tags.
*
* {@link https://eminence-astro-suite.xeffen25.com/components/icons Icons}
*/
icons?: ComponentProps<typeof Icons>["icons"] | false;
/**
* Pre-serialized JSON-LD string injected as `<script type="application/ld+json">`.
* Omit to suppress.
*
* {@link https://eminence-astro-suite.xeffen25.com/components/json-ld JsonLd}
*/
jsonLd?: ComponentProps<typeof JsonLd>["jsonLd"];
/**
* Map of language codes to alternate URLs for `<link rel="alternate" hreflang>` tags.
* Omit to suppress.
*
* {@link https://eminence-astro-suite.xeffen25.com/components/language-alternates LanguageAlternates}
*/
languageAlternates?: ComponentProps<typeof LanguageAlternates>["languages"];
/**
* Web app manifest URL rendered as `<link rel="manifest">`.
* Auto-derived from `Astro.site` when omitted. Pass `false` to suppress.
*
* {@link https://eminence-astro-suite.xeffen25.com/components/manifest Manifest}
*/
manifest?: ComponentProps<typeof Manifest>["href"] | false;
/**
* Open Graph metadata props forwarded to the `OpenGraph` component.
* Omit to suppress all `og:` tags.
*
* {@link https://eminence-astro-suite.xeffen25.com/components/open-graph OpenGraph}
*/
openGraph?: ComponentProps<typeof OpenGraph>;
/**
* Robots directive props controlling search engine crawling and indexing.
* Falls back to integration config.
*
* {@link https://eminence-astro-suite.xeffen25.com/components/robots Robots}
*/
robots?: ComponentProps<typeof Robots>;
/**
* Theme color value(s) for the browser UI chrome.
* Falls back to integration config. Pass `false` to suppress.
*
* {@link https://eminence-astro-suite.xeffen25.com/components/theme-color ThemeColor}
*/
themeColor?: ThemeColorValue | false;
/**
* Site ownership verification tokens for search engine consoles.
* Falls back to integration config. Pass `false` to suppress.
*
* {@link https://eminence-astro-suite.xeffen25.com/components/verification Verification}
*/
verification?: ComponentProps<typeof Verification> | false;
}
const {
charset,
viewport,
base,
title,
titleTemplate,
appleItunesApp,
canonical,
colorScheme,
description,
generator,
humansTxt,
icons,
jsonLd,
languageAlternates,
manifest,
openGraph,
robots,
themeColor,
verification,
extend,
} = Astro.props;
---
<head>
{charset !== false && <Charset charset={charset} />}
{viewport !== false && <Viewport content={viewport} />}
{base !== false && <Base {...(base ?? {})} />}
<Title value={title} template={titleTemplate} />
<slot />
<Extend {...extend ?? {}} />
{appleItunesApp !== false && <AppleItunesApp {...(appleItunesApp ?? {})} />}
{canonical !== false && <Canonical href={canonical} />}
{colorScheme !== false && <ColorScheme content={colorScheme} />}
<Description content={description} />
{generator !== false && <Generator generate={generator} />}
{humansTxt !== false && <HumansTxt href={humansTxt} />}
{icons !== false && <Icons icons={icons} />}
{jsonLd && <JsonLd jsonLd={jsonLd} />}
{languageAlternates && <LanguageAlternates languages={languageAlternates} />}
{manifest !== false && <Manifest href={manifest} />}
{openGraph && <OpenGraph {...openGraph} />}
<Robots {...robots ?? {}} />
{
themeColor !== false &&
(typeof themeColor === "string" ? (
<ThemeColor content={themeColor} />
) : themeColor ? (
<ThemeColor {...themeColor} />
) : (
<ThemeColor />
))
}
{verification !== false && <Verification {...verification} />}
</head>