Back

Astro 网站本地化快速指南

Astro 网站本地化快速指南

构建多语言 Astro 网站?您需要处理两个不同的挑战:按语言组织内容页面以及翻译按钮和导航等 UI 元素。本指南将向您详细展示如何在 Astro 中设置静态和动态本地化,从基础配置到生产就绪功能。

核心要点

  • 配置 Astro 内置的 i18n 路由以实现自动 URL 生成和内容组织
  • 使用带有 [locale] 文件夹的动态路由来避免重复页面文件
  • 集成 Paraglide 实现类型安全的 UI 字符串翻译,同时最小化打包体积影响
  • 利用 Astro 的辅助函数如 getRelativeLocaleUrl() 来防止常见的路由错误

为静态内容设置 Astro i18n 路由

在 astro.config.mjs 中配置多语言支持

首先在 astro.config.mjs 文件中配置 Astro 内置的 i18n 路由。这告诉 Astro 您支持哪些语言以及如何构建 URL:

import { defineConfig } from 'astro/config';

export default defineConfig({
  i18n: {
    defaultLocale: 'en',
    locales: ['en', 'es', 'fr'],
    routing: {
      prefixDefaultLocale: true // 为英语 URL 使用 /en/
    }
  }
});

设置 prefixDefaultLocale: true 确保所有语言使用一致的 URL 模式(/en/about/es/about),这样更容易管理链接并避免后续的路由冲突。

创建本地化文件夹结构

通过在 src/pages/ 中创建特定语言环境的文件夹来组织您的页面:

src/pages/
  en/
    index.astro
    about.astro
  es/
    index.astro
    about.astro
  fr/
    index.astro
    about.astro

每个文件夹对应配置中定义的一个语言环境。Astro 会根据这个结构自动生成正确的路由。

在 Astro 中管理静态和动态本地化

按语言环境组织内容集合

对于博客文章、文档或任何内容集合,使用相同的语言环境结构:

src/content/
  blog/
    en/
      first-post.md
    es/
      first-post.md
    fr/
      first-post.md

查询内容时,按当前语言环境进行过滤:

import { getCollection } from 'astro:content';

const posts = await getCollection('blog', ({ id }) => {
  return id.startsWith(Astro.currentLocale + '/');
});

使用 [locale] 文件夹实现动态路由

不要为每种语言复制页面文件,而是使用动态路由。创建一个 [locale] 文件夹:

src/pages/
  [locale]/
    index.astro
    about.astro
    blog/
      [slug].astro

在您的页面中,使用 getStaticPaths() 为所有语言环境生成路由:

export function getStaticPaths() {
  return [
    { params: { locale: 'en' } },
    { params: { locale: 'es' } },
    { params: { locale: 'fr' } }
  ];
}

使用 Paraglide 处理动态 UI 字符串

为 Astro 安装和配置 Paraglide

虽然 Astro 处理页面路由,但您需要一个解决方案来处理 UI 文本。Paraglide 提供出色的 TypeScript 支持和最小的打包体积:

npm install @inlang/paraglide-js @inlang/paraglide-astro
npx @inlang/paraglide-js init

创建翻译文件和消息键

在项目根目录的 messages/ 中存储您的翻译:

// messages/en.json
{
  "nav.home": "Home",
  "nav.about": "About",
  "button.readMore": "Read more"
}

// messages/es.json
{
  "nav.home": "Inicio",
  "nav.about": "Acerca de",
  "button.readMore": "Leer más"
}

在组件中导入和使用翻译:

---
import * as m from '../paraglide/messages.js';
---

<nav>
  <a href={`/${Astro.currentLocale}`}>{m.nav_home()}</a>
  <a href={`/${Astro.currentLocale}/about`}>{m.nav_about()}</a>
</nav>

构建语言切换器和导航

使用 getRelativeLocaleUrl() 生成简洁的 URL

Astro 提供辅助函数来生成正确的本地化 URL。始终使用 getRelativeLocaleUrl() 而不是手动字符串拼接:

import { getRelativeLocaleUrl } from 'astro:i18n';

const aboutUrl = getRelativeLocaleUrl(Astro.currentLocale, 'about');
const blogUrl = getRelativeLocaleUrl(Astro.currentLocale, 'blog/my-post');

创建语言切换器组件:

---
import { getRelativeLocaleUrlList } from 'astro:i18n';

const localeUrls = getRelativeLocaleUrlList();
---

<select onchange="window.location.href = this.value">
  {localeUrls.map(url => {
    const locale = url.split('/')[1];
    return (
      <option value={url} selected={Astro.currentLocale === locale}>
        {locale.toUpperCase()}
      </option>
    );
  })}
</select>

避免双重前缀路由等常见陷阱

注意这些常见错误:

  1. 双重前缀:使用动态路由时,清理您的 slug 以避免像 /en/blog/en/my-post 这样的 URL:
const cleanSlug = post.slug.replace(`${locale}/`, '');
  1. 硬编码语言环境路径:始终使用 Astro 的 i18n 辅助函数而不是字符串拼接
  2. 链接中缺少语言环境:每个内部链接都需要适当的本地化

Astro i18n 高级功能

设置回退语言

为未翻译的内容配置回退:

export default defineConfig({
  i18n: {
    defaultLocale: 'en',
    locales: ['en', 'es', 'fr'],
    fallback: {
      es: 'en',
      fr: 'en'
    },
    routing: {
      fallbackType: 'rewrite' // 显示回退内容而不重定向
    }
  }
});

为生产环境配置域名映射

对于每种语言使用单独域名的生产网站:

export default defineConfig({
  i18n: {
    defaultLocale: 'en',
    locales: ['en', 'es', 'fr'],
    domains: {
      fr: 'https://fr.example.com',
      es: 'https://example.es'
    }
  }
});

这需要使用 @astrojs/node@astrojs/vercel 适配器进行服务端渲染。

结论

本地化 Astro 网站结合了两种方法:用于静态内容组织的内置 i18n 路由和用于动态 UI 字符串的外部库(如 Paraglide)。从文件夹结构和路由配置开始,然后分层添加翻译管理。记住使用 Astro 的 URL 辅助函数来避免常见的路由问题,并考虑为生产部署配置回退和域名映射。

常见问题

是的,您可以通过保留当前页面并在语言环境文件夹中添加本地化版本来逐步迁移。使用重定向将用户从旧 URL 转换到新的本地化 URL,同时保持 SEO 价值。

使用 JavaScript Intl API 配合 Astro.currentLocale 进行格式化。创建接受语言环境并返回适合每种语言的格式化日期、数字和货币的实用函数。

在布局中实现 hreflang 标签,告诉搜索引擎语言替代版本。Astro 的 i18n 路由自动处理 URL 结构,但您需要添加适当的元标签以获得最佳的国际 SEO 效果。

Gain Debugging Superpowers

Unleash the power of session replay to reproduce bugs, track slowdowns and uncover frustrations in your app. Get complete visibility into your frontend with OpenReplay — the most advanced open-source session replay tool for developers. Check our GitHub repo and join the thousands of developers in our community.

OpenReplay