Skip to content
Back to the blog

Check multilingual Astro: routes, canonical URLs and hreflang

Check eight Astro routes in four languages: page identity, language switching, canonical URLs, hreflang and 404s with a locally tested MIT example.

  • Astro
  • i18n
  • SEO

A translated website needs more than a language selector. Each page needs a URL that exists, displays the corresponding content and links to its translations. If you switch to French from “About the project”, landing on the French homepage loses the context even if the link returns a 200.

This diagnostic uses an original static Astro example with two pages in Spanish, English, French and Catalan. The local trial checks the artefact before choosing hosting; it does not demonstrate native delivery on Hostbrid or SSR support. It includes no forms, accounts, API, automatic translation or language detection, or content generated during a request.

Define equivalent pages before generating URLs

Our map uses a page identity independent of its language and slug. The homepage has four addresses: /es/, /en/, /fr/ and /ca/. The second page uses /es/sobre/, /en/about/, /fr/a-propos/ and /ca/sobre/.

Switching languages should preserve the page identity. From /es/sobre/, the French link points to /fr/a-propos/; simply replacing the prefix to produce /fr/sobre/ is not enough. That address is not part of the map. Nor is it enough for a fallback rule to return any HTML: you need to check which page you received.

A question from January 17, 2025 asks to preserve the page when switching from English to Spanish; it illustrates a navigation need, not a diagnosis of the current API.

In this example, routes are generated using getStaticPaths and an explicit map. This describes the example’s implementation, not a new Astro configuration option or a requirement for middleware. If your project uses another strategy, review its generated routes and actual behaviour. Also consult the official Astro internationalization documentation to compare your project’s strategy.

Keep canonical URLs and alternates separate

The canonical URL for /fr/a-propos/ should identify that French version. The hreflang links describe the other equivalent versions, including the page itself. Every version in the group should return the same set of equivalents and link reciprocally.

In the example, x-default points to the equivalent English version. This is an editorial choice for the example, not a requirement to use English or a promise about rankings. You can choose another version or a language selection page if it exists and suits your website. Consult Google’s documentation on localized versions.

The lang attribute and visible content should match the page’s language. A link labelled “Français” does not make a page French if it keeps the Spanish text. Also review navigation, image alternative text and inner pages.

Check the files you will publish

Before choosing hosting, identify whether Astro produces static files or needs a server. This example uses static output: pages are computed during the build. That does not demonstrate that another project with sessions, API or rendering on each request can be published in the same way.

The local trial verified the eight pages served over HTTP and 16 Chrome renders: each page at 390 and 1280 pixels, with DPR 2, direct navigation and a reload fetching a new document. It checked CSS, the image, ready fonts, links to the equivalent language version and the absence of horizontal overflow.

For the negative control, we changed only the generated HTML of the Spanish “About” page: its Catalan alternate pointed to /ca/absent/. The destination returned a real 404 and the verifier rejected that relationship. We then restored the original bytes and the check passed again. The verifier uses a URL contract independent of the map that generates the application.

The example pins Astro 7.3.7, Node 22.23.3 and npm 10.9.9. Its README explains how to run the trial in a clean copy with Chrome on macOS. The canonical origin used during the test is https://atlas.example.invalid: it is deliberately fictional. Before a real publication, configure the intended domain and verify the public destinations again; that hostname is not an accessible demo.

What the local artefact demonstrates

The local test checks the files and the relationships between versions. It does not validate the final domain or a hosting configuration. When publishing your project, check the eight routes corresponding to your map, each page’s identity, its assets and the 404 responses again.

If your website includes dynamic features, keep a separate inventory of the server and external services before purchasing hosting. The articles on publishing static Astro and choosing hosting help separate those decisions.

Reproduce the reviewed example

The original MIT-licensed repository contains the code and checker. These commands pin the reviewed revision. The experiment requires Node 22.23.3, its bundled npm 10.9.9 and Chrome on macOS; read the README before running it. Use a new directory to preserve the evidence.

git clone https://github.com/ocentelles/hostbrid-example-astro-i18n.git
cd hostbrid-example-astro-i18n
git checkout 8c6ad19b60fcd67318b4c312ddfac852f146863d
node --version
node scripts/run-essay.mjs /tmp/my-astro-i18n-evidence

Manage your sites, servers and email.

Forgot your password?

Free, and it takes a minute.

At least 8 characters. Not all digits, not a common one.

We'll email you to confirm the account.