Astro multilingual SEO starts with URL structure

A practical guide to Astro multilingual blog SEO, covering locale URLs, canonical tags, hreflang, translation keys, sitemap behavior, and common failure modes.

The hard part of a multilingual blog is not the first translation. The hard part is keeping URLs, canonical tags, language alternates, feeds, and internal links correct after the third or fourth post.

The short answer: decide the URL model first, then generate canonical and hreflang links from the same content relationship.

Astro is a good fit for this because it can generate static HTML and validate Markdown metadata through content collections. But Astro does not decide your multilingual SEO model for you. That part should be explicit.

Use visible locale URLs

For a technical blog, visible locale prefixes are easier to operate than browser-language redirects.

/ko/posts/astro-multilingual-seo-url-structure/
/en/posts/astro-multilingual-seo-url-structure/

This keeps the document address stable. A search crawler, a feed reader, or a person sharing the URL can see which language the page is in.

Model Good for Watch out for
/ko and /en prefixes Clear multilingual sites Default locale handling
/ as default, /en as alternate Local-first blogs Root canonical and x-default
Automatic language redirect Apps with user preference Crawlers and slow networks

For a public blog, I would avoid hiding the first page behind a JavaScript redirect. Render useful HTML at the root, then provide language alternates.

Keep a translation key

Do not rely on titles or filenames to connect translations. Titles change. Slugs can change. A stable translationKey gives the site one internal relationship to work with.

---
title: "Astro Multilingual SEO: Start with URL Structure"
lang: "en"
translationKey: "astro-multilingual-seo-url-structure"
---

The Korean version can use the same key:

---
title: "Astro 다국어 블로그 SEO: URL 구조를 먼저 정해야 하는 이유"
lang: "ko"
translationKey: "astro-multilingual-seo-url-structure"
---

That key can drive language switching, alternate links, sitemap logic, related posts, and editorial checks.

Canonical and hreflang are not the same thing

Canonical tells search engines which URL is the preferred version of a page. Hreflang tells them which language or regional alternatives exist.

An English post should canonicalize to itself:

<link rel="canonical" href="https://example.com/en/posts/foo/" />

Then it can list alternatives:

<link rel="alternate" hreflang="ko" href="https://example.com/ko/posts/foo/" />
<link rel="alternate" hreflang="en" href="https://example.com/en/posts/foo/" />
<link
  rel="alternate"
  hreflang="x-default"
  href="https://example.com/ko/posts/foo/"
/>

The Korean post should also canonicalize to itself. Do not point every translation to one language as canonical. Different language pages are not duplicate pages; they are alternate versions.

Sitemap entries should match real pages

A multilingual sitemap should include the pages that actually exist.

https://example.com/ko/posts/foo/
https://example.com/en/posts/foo/

If the English version does not exist, do not invent an English hreflang URL. Missing alternates are better than broken alternates.

The same rule applies to internal language switchers. A language switch should point to the translated article when it exists, and to the localized posts index only when it does not.

A practical Astro boundary

A clean Astro setup usually separates the work like this:

Area Example file Responsibility
Routing src/pages/[lang]/posts/[slug].astro Build localized URLs
Content src/content/posts/{lang} Markdown and frontmatter
SEO src/lib/seo.ts Title, description, canonical
Alternates src/lib/alternates.ts translationKey matching
Layout BaseLayout.astro Render head tags

The point is not abstraction for its own sake. The point is that adding a Markdown file should update the article page, list page, RSS feed, sitemap, and structured data without manual edits in five places.

Common failure modes

[ ] Every language page uses the same canonical URL
[ ] hreflang points to pages that do not exist
[ ] the root page is only a visible redirect shell
[ ] English metadata is copied from Korean metadata
[ ] URLs are localized but the body language is not
[ ] sitemap includes only the default language

The first failure is the most damaging. If all language pages canonicalize to the Korean page, the English page may look like a duplicate instead of a valid alternate.

When to translate

Not every post needs an English version. Translate posts when the search intent is global.

Topic English value
Astro, GitHub Pages, Cloudflare, Vercel High
Naver Search Advisor Low
GA4, AdSense, consent, privacy High
Personal product decisions Medium

A small blog can translate fewer posts if the translated posts are the ones with global search demand.

Sources