Guides
Astro SEO Checklist: Static Output and Selective Hydration
Astro ships zero JavaScript by default and renders to static HTML. That removes the entire category of rendering problems, which leaves only the ordinary work.
Run a fresh DomainLens audit and use the report as your priority list.
Why the starting position is good
Astro renders components to HTML at build time and sends no JavaScript unless you explicitly ask for it. A crawler receives a complete document on the first pass with nothing to execute, which is the ideal case.
That means the JavaScript SEO problems that dominate React and Vue discussions simply do not arise. What remains is metadata, canonicals, sitemaps and content — the same work every static site needs.
Metadata in a layout
Astro has no metadata API; you write the head yourself. That is more explicit and slightly more error-prone, so put it in a shared layout rather than repeating it per page.
---
// src/layouts/Base.astro
const { title, description, image } = Astro.props;
const canonical = new URL(Astro.url.pathname, Astro.site);
---
<head>
<title>{title}</title>
<meta name="description" content={description} />
<link rel="canonical" href={canonical} />
<meta property="og:title" content={title} />
<meta property="og:image" content={image} />
</head>
<!-- Astro.site must be set in astro.config for the
canonical to resolve to an absolute URL. -->
The checklist
The 404 status depends on the host rather than on Astro. Static hosts differ: some serve 404.html with a 404 status, others with a 200. Test it, because a static site with soft 404s has the same unbounded problem an SPA does.
- 1Set the site option in astro.config so canonical URLs and the sitemap resolve absolutely.
- 2Add the sitemap integration rather than maintaining a file by hand.
- 3Handle title, description and canonical in a base layout, with per-page props.
- 4Add a 404.astro page — and confirm your host returns a 404 status with it, not a 200.
- 5Use client directives sparingly; every hydrated island is JavaScript you chose to ship.
- 6Set explicit width and height on images and avoid lazy-loading the LCP element.
Islands, and when they cost you
Astro's selective hydration means you ship interactive components only where needed. The SEO consequence is small but real: content inside an island rendered with client:only never exists in the HTML at all, so it is invisible to the first pass exactly as in any SPA.
The other directives — client:load, client:idle, client:visible — all render on the server first, so the content is present and only the interactivity is deferred. Only client:only removes the server render.
| Directive | Server-rendered? | Safe for content |
|---|---|---|
| none (default) | Yes, no JS shipped | Yes |
| client:load | Yes | Yes |
| client:idle | Yes | Yes |
| client:visible | Yes | Yes |
| client:only | No | No — content is absent |
Static or server output
Astro can also run in server mode with an adapter, which is the right choice for genuinely dynamic content. The SEO properties are the same either way — both produce complete HTML. Choose on whether the content needs to be fresh per request, not on search considerations. See JavaScript SEO for what static output is protecting you from.
How DomainLens contributes
DomainLens reads the served HTML, which for an Astro site is the whole story — the audit sees exactly what a crawler sees. It reports the canonical, metadata and Core Web Vitals so you can confirm the layout is doing its job across templates. See the technical SEO checklist for the platform-agnostic sequence.
- Is Astro good for SEO?
- It has the best default position of any modern framework: complete HTML with no JavaScript required. The remaining work is metadata and content, which every site needs.
- Does Astro add canonical tags?
- No. Write them in a layout using Astro.url and Astro.site, which must be configured for the URL to resolve absolutely.
- Does client:only hurt SEO?
- For content, yes — nothing inside it exists in the HTML. Use it only for genuinely interactive widgets that carry no indexable content.
- Will my Astro 404 page return a 404 status?
- It depends on the host, not on Astro. Some static hosts serve 404.html with a 200. Test it with curl before assuming.