Metadata & SEO
The meta field declares everything that appears in the <head> — title, description, stylesheets, Open Graph tags, and structured data. All metadata is rendered server-side, so crawlers and social media scrapers see the final HTML without executing JavaScript.
Basic metadata
export default {
route: '/about',
meta: {
title: 'About Us — Acme Corp',
description: 'Learn about the team behind Acme Corp.',
styles: ['/app.css'],
},
state: {},
view: () => `<h1>About Us</h1>`,
}
This generates:
<"tok-fn">class="tok-kw">title>About Us — Acme Corp</"tok-fn">class="tok-kw">title>
<"tok-fn">class="tok-kw">meta "tok-fn">name="description" "tok-fn">content="Learn about the team behind Acme Corp.">
<"tok-fn">class="tok-kw">link "tok-fn">rel="stylesheet" "tok-fn">href="/app.css">
All meta fields
| Field | Type | Description |
|---|---|---|
title | string | Page title — appears in the browser tab and search results. |
description | string | Meta description — appears in search engine snippets. Keep under 160 characters. |
styles | string[] | Array of stylesheet URLs — each emits a <link rel="stylesheet"> tag. |
ogTitle | string | Open Graph title. If omitted, falls back to title. |
ogImage | string | Open Graph image URL — shown when the page is shared on social media. |
schema | object | JSON-LD structured data object — emitted as a <script type="application/ld+json"> tag. |
Open Graph
Open Graph tags control how the page appears when shared on social media (Twitter/X, Facebook, LinkedIn, Slack, etc.):
meta: {
title: 'My Product — Acme Corp',
description: 'The best product ever made.',
ogTitle: 'My Product', // shorter for social
ogImage: 'https://acme.com/og/my-product.jpg', // 1200×630 recommended
}
Generated tags:
<"tok-fn">class="tok-kw">meta "tok-fn">property="og:title" "tok-fn">content="My Product">
<"tok-fn">class="tok-kw">meta "tok-fn">property="og:description" "tok-fn">content="The best product ever made.">
<"tok-fn">class="tok-kw">meta "tok-fn">property="og:image" "tok-fn">content="https://acme.com/og/my-product.jpg">
<"tok-fn">class="tok-kw">meta "tok-fn">name="twitter:card" "tok-fn">content="summary_large_image">
<"tok-fn">class="tok-kw">meta "tok-fn">name="twitter:title" "tok-fn">content="My Product">
<"tok-fn">class="tok-kw">meta "tok-fn">name="twitter:image" "tok-fn">content="https://acme.com/og/my-product.jpg">
Use an absolute URL for
ogImage — social media crawlers need the full URL to fetch the image. Recommended size: 1200×630 pixels.Structured data (ld+json)
The schema field accepts a plain object conforming to schema.org vocabulary. Pulse serialises it as a <script type="application/ld+json"> tag in the head:
meta: {
title: 'How to make sourdough — My Blog',
schema: {
'@context': 'https://schema.org',
'@type': 'Article',
headline: 'How to make sourdough',
author: {
'@type': 'Person',
name: 'Jane Smith',
},
datePublished: '2025-01-15',
image: 'https://myblog.com/sourdough.jpg',
},
}
Common schema types:
| @type | Use for |
|---|---|
WebSite | The homepage or site root |
WebPage | General pages |
Article | Blog posts, news articles |
Product | E-commerce product pages |
FAQPage | FAQ pages (enables rich results in Google) |
BreadcrumbList | Breadcrumb navigation |
Organization | Company/brand information |
Stylesheets
The styles array accepts any number of stylesheet URLs. They are emitted as <link rel="stylesheet"> tags in the <head> in the order declared:
meta: {
styles: [
'/app.css',
'/fonts.css',
'https://fonts.googleapis.com/css2?family=Inter:wght@400;600&display=swap',
],
}
For maximum performance, host your own fonts rather than using Google Fonts. External stylesheet requests add render-blocking latency and a DNS lookup.
SEO tips
- Write a unique
titleanddescriptionfor every page — duplicate metadata prevents pages from competing in search results. - Keep descriptions under 160 characters — longer values are truncated.
- Use structured data to qualify for Google rich results.
- All metadata is in the server-rendered HTML — search engines and social scrapers do not need to execute JavaScript to read it.
- Pulse targets 100/100 Lighthouse SEO out of the box. Run
/pulse-reportafter new pages to confirm.