SEO
Page SEO component
Centralize meta tags in a single component slotted into the layout head. Typical props:
| Prop |
Type |
Notes |
title |
string |
Page title, used for <title>, OG, Twitter |
description |
string |
Meta description (≤ 160 chars) |
canonicalUrl |
string? |
Defaults to Astro.url.href |
ogImage |
string? |
Absolute URL, 1200×630 PNG |
ogType |
'website' | 'article'? |
Defaults to website |
twitterCard |
string? |
Defaults to summary_large_image |
noIndex |
boolean? |
Adds noindex,nofollow |
Generated output:
<title> and <meta name="description">
<link rel="canonical">
<meta property="og:title|description|type|url|image">
<meta name="twitter:card|title|description|image">
<script type="application/ld+json"> (WebPage schema)
Open Graph images
- 1200 × 630 PNG, generated at build time (Satori + resvg is a solid stack).
- One image per page; blog posts derive from frontmatter at build time.
- Reference with absolute URLs:
new URL('/og/page.png', Astro.site).href.
- Maintain parity across locales — every localized page needs its own OG image.
Sitemap
Generate /sitemap.xml from static routes plus collection entries:
import { getCollection } from 'astro:content';
export const GET = createSitemapRoute({
siteUrl: import.meta.env.SITE,
pageModules: import.meta.glob('./**/*.astro', { eager: true }),
getBlogPosts: () => getCollection('blog'),
blogPrefix: '/blog',
locales: ['de'],
exclude: ['/blog/'],
});
- Drafts are excluded because
getStaticPaths filters them — no page is generated, so the sitemap is clean by construction.
<urlset> is the standard root element — include <lastmod> where you have a reliable modification date.
robots.txt
User-agent: *
Allow: /
Sitemap: https://example.com/sitemap.xml
Must point at the correct absolute sitemap URL and match the configured site.
Canonical URLs
Auto-resolve from Astro.url.href. Override explicitly for:
- Paginated archives pointing at the canonical first page.
- Syndicated content pointing at the original.
- URL parameters that should not fragment ranking signals.
JSON-LD structured data
Include WebPage schema on every page automatically. For blog posts, set ogType="article" for Open Graph; you can still use WebPage schema or upgrade to Article schema with author and dates.
{
"@context": "https://schema.org",
"@type": "WebPage",
"name": "Page title",
"description": "Page description",
"url": "https://example.com/page"
}
For richer schemas (LocalBusiness, Service, FAQ, Breadcrumb) see the local-business-seo skill.
Checklist for new pages
<title> and meta description set via layout props.
- PageSEO with title, description, OG image.
- OG image generated (both locales, where applicable).
- Canonical URL resolves correctly.
- Page appears in sitemap.
hreflang alternates for localized pages.
- Page passes post-build audit (no missing title / description / canonical, no duplicate H1s).
1---2name: seo3description: On-page SEO for Astro sites — meta tags, Open Graph images (og:title, og:image), canonical URLs, sitemap.xml, robots.txt, and JSON-LD WebPage/Article schema. Use when setting up or debugging meta descriptions, OG tags, canonical links, structured data, sitemap generation, robots config, or when a page isn't indexed correctly. For LocalBusiness schema or city/regional landing pages, use local-business-seo instead.4---56# SEO78## Page SEO component910Centralize meta tags in a single component slotted into the layout head. Typical props:1112| Prop | Type | Notes |13|---|---|---|14| `title` | `string` | Page title, used for `<title>`, OG, Twitter |15| `description` | `string` | Meta description (≤ 160 chars) |16| `canonicalUrl` | `string?` | Defaults to `Astro.url.href` |17| `ogImage` | `string?` | Absolute URL, 1200×630 PNG |18| `ogType` | `'website' \| 'article'?` | Defaults to `website` |19| `twitterCard` | `string?` | Defaults to `summary_large_image` |20| `noIndex` | `boolean?` | Adds `noindex,nofollow` |2122Generated output:2324- `<title>` and `<meta name="description">`25- `<link rel="canonical">`26- `<meta property="og:title|description|type|url|image">`27- `<meta name="twitter:card|title|description|image">`28- `<script type="application/ld+json">` (WebPage schema)2930## Open Graph images3132- 1200 × 630 PNG, generated at build time (Satori + resvg is a solid stack).33- One image per page; blog posts derive from frontmatter at build time.34- Reference with absolute URLs: `new URL('/og/page.png', Astro.site).href`.35- Maintain parity across locales — every localized page needs its own OG image.3637## Sitemap3839Generate `/sitemap.xml` from static routes plus collection entries:4041```typescript42import { getCollection } from 'astro:content';4344export const GET = createSitemapRoute({45 siteUrl: import.meta.env.SITE,46 pageModules: import.meta.glob('./**/*.astro', { eager: true }),47 getBlogPosts: () => getCollection('blog'),48 blogPrefix: '/blog',49 locales: ['de'],50 exclude: ['/blog/'],51});52```5354- Drafts are excluded because `getStaticPaths` filters them — no page is generated, so the sitemap is clean by construction.55- `<urlset>` is the standard root element — include `<lastmod>` where you have a reliable modification date.5657## robots.txt5859```60User-agent: *61Allow: /6263Sitemap: https://example.com/sitemap.xml64```6566Must point at the correct absolute sitemap URL and match the configured site.6768## Canonical URLs6970Auto-resolve from `Astro.url.href`. Override explicitly for:7172- Paginated archives pointing at the canonical first page.73- Syndicated content pointing at the original.74- URL parameters that should not fragment ranking signals.7576## JSON-LD structured data7778Include WebPage schema on every page automatically. For blog posts, set `ogType="article"` for Open Graph; you can still use WebPage schema or upgrade to Article schema with author and dates.7980```json81{82 "@context": "https://schema.org",83 "@type": "WebPage",84 "name": "Page title",85 "description": "Page description",86 "url": "https://example.com/page"87}88```8990For richer schemas (LocalBusiness, Service, FAQ, Breadcrumb) see the `local-business-seo` skill.9192## Checklist for new pages9394- `<title>` and meta description set via layout props.95- PageSEO with title, description, OG image.96- OG image generated (both locales, where applicable).97- Canonical URL resolves correctly.98- Page appears in sitemap.99- `hreflang` alternates for localized pages.100- Page passes post-build audit (no missing title / description / canonical, no duplicate H1s).