Using Astro for SEO is less about the framework and more about what you add to it. Astro is a build tool, not a CMS. It will not write a meta description, add a canonical tag or generate a sitemap unless you tell it to. That suits developers who want control, and it catches out anyone who expects WordPress-style defaults. This post covers the short list of things to set up, in the order that matters.
Why pre-rendered pages are the right starting point
For static routes, Astro builds each page to HTML ahead of time. When a crawler requests the page, the content is already in the response. It does not depend on JavaScript running first, which is where many sites built on client-side frameworks run into indexing trouble. Our guide to JavaScript SEO covers those problems in detail.
That advantage holds as long as your content stays in the HTML. Interactive components that load content only in the browser bring the old risks back for that part of the page. If you also use server rendering for some routes, the trade-offs are different again; our explainer on server-side rendering and SEO covers how the two compare. For a content site, pre-rendering the pages you want ranked is the simplest choice.

Set up the sitemap integration
Astro does not create a sitemap on its own. The official integration does, and its documentation, @astrojs/sitemap, says it “generates a sitemap based on your pages when you build your Astro project.” The key facts are in the table.
| Aspect | @astrojs/sitemap |
|---|---|
| When it runs | At build time |
| Required setting | The site option in astro.config.mjs |
| Static routes | Included |
Dynamic routes from getStaticPaths() | Included |
| Dynamic routes in SSR mode | Cannot be generated |
entryLimit default | 45,000 entries; beyond that, a sitemap index plus multiple sitemaps |
The site option is the step people miss. The integration needs your full domain to write absolute URLs, so without it there is no sitemap. A minimal config looks like this:

After the next build, look in the output folder for the sitemap files and open them. Confirm the URLs use your production domain and include the pages you expect. Then add a Sitemap: line pointing to the index file in your robots.txt, and submit the same address in Search Console. Our guides to XML sitemaps and robots.txt cover both files.
The 45,000-entry default only matters on large sites, such as programmatic builds with thousands of generated pages. When a site passes it, the integration splits the output into a sitemap index and several sitemaps, and the index is the one address you submit. On a typical blog or marketing site you will never notice the limit.
Write the head once, in a layout
Astro will output exactly the head you write. The practical approach is a single layout or head component that every page uses, taking a title and description as props. That way each page sets its own values, and nothing ships without them.

Building the canonical URL from Astro.site keeps it on your production domain, even when the same build is previewed elsewhere. Decide on trailing slashes once and keep canonicals, internal links and the sitemap consistent with that choice. Our guide to the canonical tag explains why mismatches matter, and the SEO title length guide covers how long titles should be.
Social tags and structured data belong in the same component. Open Graph tags control how links look when shared; JSON-LD tells search engines what a page is. Neither appears unless you add it, so add both while you are building the layout rather than as an afterthought. Our schema markup guide covers which types fit which pages.
Images need the same discipline. Alt text is whatever you pass to each image, so make it a required prop in your image component rather than an optional one. A build that fails on a missing description is easier to live with than a site that quietly ships hundreds of empty alt attributes. Our guide to image alt text covers what to write.

Astro and SEO on server-rendered routes
Astro can also render pages on request. That is useful for personalised or frequently changing content, but it creates one specific gap: the sitemap integration cannot generate entries for dynamic routes in SSR mode, because there is no list of pages at build time. If those pages need to rank, you have to list them some other way, for example with a separately generated sitemap, or pre-render them instead.
Server-rendered pages also need their head built correctly on every request. Test a few with a fetch of the raw HTML, not just in the browser, and check that the title, description, canonical and content are all there before any script runs.
The simplest rule for a content site is to pre-render by default and server-render only where you have a clear reason. Articles, guides and category pages rarely change between requests, so building them ahead of time costs nothing and keeps them in the sitemap automatically. Reserve on-request rendering for pages that genuinely need it, and check that those pages are either listed elsewhere or not meant to rank.

What Astro will not do for you
Astro and SEO fit well technically, but a fast, clean build is a starting point. The framework does not choose what to write about, structure your internal links or earn backlinks. Those decide most of where a site ranks, whatever it is built with.
Internal linking is the one area where a framework build often falls behind a CMS. With no plugin suggesting related posts, links between articles happen only if you write them or build a component that adds them. Plan the main topic clusters early and link within them deliberately; our guide to internal linking covers how.

Run through a short launch check. Is site set? Does the sitemap list only production URLs? Does every page have a unique title and description? Are canonicals absolute and consistent? Is the content in the raw HTML? Our technical SEO checklist covers the rest of a launch audit, and the page speed guide covers what to measure once the site is live.
The limitation is that this post covers the official sitemap integration and core behaviour as documented when we checked. Astro releases often, integrations change their options, and community packages for meta tags and structured data vary widely. Check the current documentation for your version before relying on any default described here, and verify the built output rather than the config.
Frequently asked questions
Is Astro good for SEO?
Its pre-rendered pages give search engines content in the HTML, which is a strong technical base. Titles, descriptions, canonicals and the sitemap still have to be set up.
Does Astro generate a sitemap automatically?
Not on its own. Add the @astrojs/sitemap integration and set the site option in astro.config.mjs; it then generates a sitemap at build time.
Why is my Astro sitemap missing pages?
The integration cannot generate entries for dynamic routes in SSR mode. Pre-render those routes, or list them in a sitemap you generate another way.
How many URLs fit in one Astro sitemap?
The entryLimit option defaults to 45,000. Beyond that, the integration produces a sitemap index plus multiple sitemaps.
The takeaway Astro’s pre-rendered pages are a clean technical base. Set the site URL, add the sitemap integration, build one solid head component, and verify the built output.

