{ }
Published on

Generate SEO Sitemaps for Multilingual Astro Sites (2025 Guide)

Authors
  • avatar
    Name
    Ahmed Farid
    Twitter
    @

TIP

Correct hreflang and sitemap strategy is the fastest way to improve indexation of multilingual content.

This tutorial will show you how to build a SEO-ready sitemap for a fully static Astro site that ships multiple language routes (/, /fr/, /ar/, …). We will:

  1. Structure routes and content folders per locale.
  2. Annotate pages with rel="alternate" hreflang="…".
  3. Generate a combined sitemap.xml with language alternates using astro-sitemap plugin.
  4. Automate sitemap submission to Google & Bing after each deploy.

The final setup works with any hosting provider (Netlify, Vercel, GitHub Pages) and requires zero server-side code.

Table of Contents

1. Prerequisites & Terminology

  • Node.js 20.
  • Astro 4.0 static output (adapter-static).
TermMeaning
hreflangHTML attribute indicating language/region variant
x-defaultFallback hreflang value when no locale fits

2. Project Structure

src/pages/
  index.astro           (en)
  fr/index.astro        (fr)
  ar/index.astro        (ar)
  [...slug]/index.astro dynamic MDX pages
src/content/
  en/blog/*.mdx
  fr/blog/*.mdx
  ar/blog/*.mdx

Each locale lives in its own folder. Astro route globbing automatically maps /fr/about to src/pages/fr/about.astro.

3. Install astro-sitemap & Mark Routes

yarn add @astrojs/sitemap@latest

astro.config.mjs:

import { defineConfig } from 'astro/config'
import sitemap from '@astrojs/sitemap'
import mdx from '@astrojs/mdx'

export default defineConfig({
  output: 'static',
  site: 'https://example.com',
  integrations: [
    mdx(),
    sitemap({
      i18n: {
        defaultLocale: 'en',
        locales: ['en', 'fr', 'ar'],
      },
    }),
  ],
})

Key points:

  • site must be absolute and https.
  • The i18n block makes the plugin add <xhtml:link rel="alternate" hreflang="…"> entries in the generated XML.

4. Add hreflang Tags in Head

Create a reusable component components/HreflangLinks.astro:

---
export interface Props { slug: string }
const { slug } = Astro.props;
const locales = ['en', 'fr', 'ar'];
---
<head>
  {locales.map(l => (
    <link
      rel="alternate"
      hreflang={l}
      href={`https://example.com/${l === 'en' ? '' : l + '/'}${slug}`}
    />
  ))}
  <link rel="alternate" hreflang="x-default" href={`https://example.com/${slug}`} />
</head>

Include at the top of each page layout:

<HreflangLinks slug={Astro.url.pathname.replace(/^\/(en|fr|ar)\/?/, '')} />

5. Dynamic MDX Collection Support

astro-sitemap automatically indexes any static route. For dynamic collections using getStaticPaths, return a locale param so the plugin can resolve alternates:

export async function getStaticPaths() {
  return languages.flatMap((lang) =>
    posts(lang).map((post) => ({
      params: { slug: post.slug },
      props: { lang, post },
    }))
  )
}

6. Build & Inspect Sitemap

yarn build
cat dist/sitemap-index.xml

You should see entries:

<url>
  <loc>https://example.com/fr/</loc>
  <xhtml:link rel="alternate" hreflang="en" href="https://example.com/" />
  <xhtml:link rel="alternate" hreflang="fr" href="https://example.com/fr/" />
  <xhtml:link rel="alternate" hreflang="ar" href="https://example.com/ar/" />
</url>

7. Ping Search Engines on Deploy

Add a deploy script in package.json:

"scripts": {
  "postdeploy": "curl -s https://www.google.com/ping?sitemap=https://example.com/sitemap-index.xml && curl -s https://www.bing.com/ping?sitemap=https://example.com/sitemap-index.xml"
}

Configure Netlify Build Hooks or Vercel post-build to run npm run postdeploy.

8. Handling Large Sites & Priority/Changefreq

astro-sitemap exposes filter and customPages options:

sitemap({
  i18n,
  filter: (page) => !page.includes('/draft/'),
  serialize: (url) => ({
    url,
    changefreq: 'weekly',
    priority: 0.7,
  }),
})

9. Testing with SEO Tools

  • Google Search ConsoleIndexing → Sitemaps.
  • Screaming Frog to verify hreflang.
  • Ahrefs Site Audit for duplicate content alerts.

10. Advanced Tips

✅ Use hreflang="ar-MA" if publishing regional dialect versions.
✅ Generate separate rss.xml per locale with @astrojs/rss.
✅ Prefetch critical locales via <link rel="preload" as="fetch">.

11. Further Reading & Resources

  • Astro docs: @astrojs/sitemap
  • Google Search Central: Multilingual & multiregional sites.
  • W3C hreflang FAQ.

12. Conclusion

With Astro’s sitemap integration plus proper hreflang markup, your multilingual static site becomes search-engine-friendly and scales automatically as you add languages. 🌍🚀