#i18 routes
3 messages · Page 1 of 1 (latest)
I understand you're having trouble translating routes in the URL with Astro's native i18n module. Let me help you with that.
Astro's built-in i18n routing doesn't directly support translating URL paths (like changing /about to /sobre-nosotros). However, you have a couple of options to implement this functionality:
Option 1: Custom locale paths
You can use Astro's custom locale paths feature to map multiple language codes to a custom URL path:
import { defineConfig } from "astro/config"
export default defineConfig({
i18n: {
locales: ["es", "en", {
path: "french", // custom path in URL
codes: ["fr", "fr-BR", "fr-CA"]
}],
defaultLocale: "en",
}
})
This approach works for language prefixes but doesn't translate individual route segments.
Internationalization API Reference
Option 2: Create a custom translation system
You can implement a custom route translation system. Here's how:
- Create a routes mapping in your i18n configuration:
// src/i18n/ui.ts
export const routes = {
de: {
'services': 'leistungen',
},
fr: {
'services': 'prestations-de-service',
},
}
- Create a helper function to translate paths:
// src/i18n/utils.ts
import { ui, defaultLang, showDefaultLang, routes } from './ui';
export function useTranslatedPath(lang: keyof typeof ui) {
return function translatePath(path: string, l: string = lang) {
const pathName = path.replaceAll('/', '')
const hasTranslation = defaultLang !== l && routes[l] !== undefined && routes[l][pathName] !== undefined
const translatedPath = hasTranslation ? '/' + routes[l][pathName] : path
return !showDefaultLang && l === defaultLang ? translatedPath : `/${l}${translatedPath}`
}
}
- Add a helper to get the route from the current URL:
export function getRouteFromUrl(url: URL): string | undefined {
const pathname = new URL(url).pathname;
const parts = pathname?.split('/');
const path = parts.pop() || parts.pop();
if (path === undefined) {
return undefined;
}
const currentLang = getLangFromUrl(url);
if (defaultLang === currentLang) {
const route = Object.values(routes)[0];
return route[path] !== undefined ? route[path] : undefined;
}
const getKeyByValue = (obj: Record<string, string>, value: string): string | undefined => {
return Object.keys(obj).find((key) => obj[key] === value);
}
const reversedKey = getKeyByValue(routes[currentLang], path);
if (reversedKey !== undefined) {
return reversedKey;
}
return undefined;
}
Option 3: Manual routing
For complete control, you can set routing: "manual" in your i18n config and implement your own routing logic:
import { defineConfig } from "astro/config"
export default defineConfig({
i18n: {
locales: ["es", "en", "fr"],
defaultLocale: "en",
routing: "manual"
}
})
This gives you full control to implement custom middleware for route translation.
Internationalization (i18n) Routing