#i18 routes

3 messages · Page 1 of 1 (latest)

waxen leafBOT
#

Hi @primal spoke. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:

#

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:

  1. Create a routes mapping in your i18n configuration:
// src/i18n/ui.ts
export const routes = {
  de: {
    'services': 'leistungen',
  },
  fr: {
    'services': 'prestations-de-service',
  },
}
  1. 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}`
  }
}
#
  1. 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;
}

Add i18n features

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

The second option (custom translation system) is likely the most straightforward approach for translating individual route segments while still leveraging Astro's built-in i18n features.

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: