Quick Start
このコンテンツはまだ日本語訳がありません。
This guide walks you through setting up @otrodigital/astro-i18n-next from scratch. By the end, you’ll have translated URL routing and i18next translations working.
-
Add the integration in
astro.config.mjs:astro.config.mjs import { defineConfig } from 'astro/config';import { createI18n } from '@otrodigital/astro-i18n-next';import en from './src/i18n/en.json' with { type: 'json' };import es from './src/i18n/es.json' with { type: 'json' };export default defineConfig({integrations: [createI18n({defaultLocale: 'en',locales: ['en', 'es'],localeLabels: { en: 'English', es: 'Español' },localeHtmlLang: { en: 'en', es: 'es' },translations: { en, es },pagesDir: 'src/pages',contentDirs: { saunas: 'src/content/saunas' },})],});The integration automatically:
- Scans
pagesDirfor.astrofiles and builds the page slug map - Scans
contentDirsfor markdown slug maps - Injects localized routes for all non-default locales
- Provides a
virtual:i18nmodule with all i18n helpers
- Scans
-
Add type declarations to
src/env.d.ts:/// <reference types="astro/client" />declare module 'virtual:i18n' {export const t: (locale: string, key: string) => string;export const localePath: (locale: string, path: string) => string;export const switchLocalePath: (currentPath: string, targetLocale: string) => string;export const getLocaleFromPath: (pathname: string) => string;export const localized: <T>(field: Record<string, T>, locale: string) => T;export const getLocalizedSlug: (category: string, canonicalSlug: string, locale: string) => string;export const getCanonicalSlug: (category: string, localizedSlug: string, locale: string) => string | undefined;export const config: import('@otrodigital/astro-i18n-next').LocaleConfig;export const defaultLocale: string;export const locales: string[];export const localeLabels: Record<string, string>;export const localeHtmlLang: Record<string, string>;} -
Add middleware for locale detection in
src/middleware.ts:import { createI18nMiddleware } from '@otrodigital/astro-i18n-next';import { config } from 'virtual:i18n';export const onRequest = createI18nMiddleware(config);This sets
Astro.locals.localeon every request based on the URL prefix. -
Use in components:
---import { t, localePath, locales } from 'virtual:i18n';const locale = Astro.locals.locale;---<h1>{t(locale, 'home.title')}</h1><a href={localePath(locale, '/about/')}>{t(locale, 'nav.about')}</a> -
Optional: export translated slugs from
.astropages:---export const slugs = { en: 'about', es: 'sobre' };import { t, localePath } from 'virtual:i18n';const locale = Astro.locals.locale;---Pages without a
slugsexport use the filename as the slug for all locales.
Create your translation files
Create JSON files for each locale:
{ "home": { "title": "Welcome" }, "nav": { "about": "About", "contact": "Contact" }}{ "home": { "title": "Bienvenido" }, "nav": { "about": "Acerca de", "contact": "Contacto" }}What happens at build time
With this setup, Astro generates:
| English (default) | Spanish |
|---|---|
/ | /es/ |
/about/ | /es/sobre/ |
/contact/ | /es/contact/ (no slug export — uses filename) |
The default locale (en) has no prefix. All other locales are prefixed (e.g., /es/).