Head Component
The <Head> component manages <head> tags from JSX. It renders nothing in the body; on the client it updates document.head directly. For programmatic HTML strings (Open Graph, JSON-LD helpers), see SEO & Meta. For route-level titles in the default SSR build, use export const metadata — SSR & SSG.
Basic Usage
import { Head } from '@emberkit/core';
function MyPage() {
return (
<>
<Head>
<title>My Page - EmberKit</title>
<meta name="description" content="A page built with EmberKit" />
</Head>
<h1>Hello World</h1>
</>
);
}
During SSR, this produces:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>My Page - EmberKit</title>
<meta name="description" content="A page built with EmberKit">
</head>
<body>
<h1>Hello World</h1>
</body>
</html>
Shorthand Props
For common tags, use props instead of raw JSX:
<Head
title="My Page"
description="Page description"
keywords={['emberkit', 'framework', 'typescript']}
author="EmberKit Team"
robots="index, follow"
canonical="https://example.com/my-page"
/>
Supported Props
Shorthand Props Reference
| Prop | Type | HTML Output |
|---|---|---|
title | string | <title> + <meta name="title"> |
description | string | <meta name="description"> |
keywords | string[] | <meta name="keywords"> (comma-separated) |
author | string | <meta name="author"> |
robots | string | <meta name="robots"> |
canonical | string | <link rel="canonical"> |
Open Graph
<Head
og={{
type: 'article',
title: 'My Page',
description: 'Page description for social sharing',
url: 'https://example.com/my-page',
image: 'https://example.com/og-image.png',
locale: 'en_US',
siteName: 'My Site',
}}
/>
Twitter Cards
<Head
twitter={{
card: 'summary_large_image',
site: '@emberkit',
creator: '@author',
title: 'My Page',
description: 'Page description',
image: 'https://example.com/twitter-image.png',
}}
/>
Combining Children and Props
You can mix shorthand props with raw JSX children:
<Head title="My Page" description="Description">
<meta property="og:image" content="https://example.com/og.png" />
<link rel="icon" href="/favicon.ico" />
</Head>
When children are provided, they take precedence — the shorthand props are ignored.
Multiple <Head> Components
Use multiple <Head> components across your component tree. All tags are collected and merged into <head>:
// Layout provides default meta
function Layout({ children }) {
return (
<>
<Head>
<meta name="theme-color" content="#0b0f19" />
<meta property="og:site_name" content="My Site" />
</Head>
{children}
</>
);
}
// Page provides page-specific meta
function AboutPage() {
return (
<>
<Head>
<title>About Us - My Site</title>
<meta name="description" content="Learn about our team" />
</Head>
<h1>About Us</h1>
</>
);
}
Structured Data (JSON-LD)
Use children for structured data scripts:
import { Head, generateArticleSchema } from '@emberkit/core';
function ArticlePage() {
const schema = generateArticleSchema({
title: 'My Article',
description: 'Article description',
author: 'John Doe',
publishedAt: '2025-01-15',
url: 'https://example.com/article',
});
return (
<>
<Head>
<title>My Article</title>
<script type="application/ld+json">{schema}</script>
</Head>
<article>
<h1>My Article</h1>
</article>
</>
);
}
How It Works
SSR
During server-side rendering, <Head>:
- Renders its children to an HTML string
- Registers the HTML to an internal head content registry
- Returns
null(nothing in the page body)
During SSR, registered tags are available via drainHeadContent() from @emberkit/core. The built-in CLI server entry injects route metadata exports; use a custom src/entry-server.tsx if you need to merge drainHeadContent() into your HTML template.
Client-Side Navigation
During SPA navigation, <Head>:
- Renders its children to an HTML string
- Parses the HTML and updates
document.headdirectly - Tags are marked with
data-ek-headso re-renders replace (not duplicate) managed tags
API Reference
interface HeadProps {
children?: JSXNode | JSXNode[];
title?: string;
description?: string;
og?: {
title?: string;
description?: string;
type?: string;
url?: string;
image?: string;
locale?: string;
siteName?: string;
};
twitter?: {
card?: string;
site?: string;
creator?: string;
title?: string;
description?: string;
image?: string;
};
canonical?: string;
robots?: string;
keywords?: string[];
author?: string;
}
Next Steps
- SEO & Meta - Programmatic meta generation with
generateMeta() - SSR - Server-side rendering pipeline
- Components - Component patterns