Introduction
Astro’s native internationalization (i18n) support (introduced in [email protected]
) simplifies building internationalized websites. This guide explores best practices, addressing common pitfalls and providing alternative solutions.
Astro provides a i18n recipe explaining how to implement i18n in your Astro project. The recipe is a great starting point, but can lead to some common pitfals.
Don’t use getRelativeLocaleUrl
to change current page language
Astro provides a great api to generate dynamic locale URLs using getRelativeLocaleUrl
. However, it’s not ideal for switching languages on the same page.
It either redirects to the root page or creates an unexpected double-prefixed URL:
-
Using
getRelativeLocaleUrl(locale: string)
in your language switcher will redirect you to the root page with the seleceted language. -
Using
getRelativeLocaleUrl("en", Astro.url.pathname)
will generate a double-prefixed URL with the current and new language as prefixese.g. /es/en/blog
.
Alternative: Custom changeLanguage Function
To solve this issue, I created a custom function changeLanguage(lang: string, path: string)
that will change the current page language and stay on the same page.
LANGUAGES = { ENGLISH: "en", SPANISH: "es", EUSKERA: "eus",};
export const showDefaultLang = false;export const defaultLang = LANGUAGES.SPANISH;
export function changeLanguage(lang: string, path: string) { const languagePrefixes = Object.values(LANGUAGES); const hasLanguagePrefix = languagePrefixes.some((prefix) => path.includes(prefix) ); if (hasLanguagePrefix) { path = path.replace(new RegExp(`/${languagePrefixes.join("|")}`), ""); } return !showDefaultLang && lang === defaultLang ? path : `/${lang}${path}`;}
showDefaultLang is a boolean that represents if the default language is in the url. This should match your Astro configuration.
defaultLang is the default language of your site. This should match your Astro configuration.
When to Use getRelativeLocaleUrl
This function shines for navigating to different pages in various locales:
<a href={`${getRelativeLocaleUrl(currentLocale, "/blog/i18n-with-astro/")}`} >
This will generate a url with the current locale as a prefix, e.g. /es/blog/i18n-with-astro/
if the current locale is Spanish.
Content Localization Beyond Astro’s i18n Recipe
Astro provides in its i18n recipe a way to show different content for different locales using . However, it’s not always the best solution, speacially for large content.
While the astro i18n recipe offers basic content translation, it might not be optimal for large amounts of text. Consider separate JSON files per language:
import english from "./en.json";import spanish from "./es.json";import euskera from "./eus.json";
export const getI18N = ({ currentLocale = "es",}: { currentLocale: string | undefined;}) => { if (currentLocale === LANGUAGES.ENGLISH) return english; if (currentLocale === LANGUAGES.SPANISH) return spanish; if (currentLocale === LANGUAGES.EUSKERA) return euskera; return spanish;};
Then we can use the getI18N
function to get the content for the current locale.
import { getI18N } from "src/i18n";const currentLocale = Astro.currentLocale ? Astro.currentLocale : "es";const i18n = getI18N({ currentLocale });
i18n
will contain the content for the current locale.
Conclusion
Astro’s i18n support empowers you to build internationalized websites effectively. By understanding common pitfalls and exploring alternative approaches, you can create seamless user experiences for diverse audiences.