- 起步
- 核心概念
- 教程
- 基础内容
- 内置功能
- 集成
- 操作指南
- 使用指南
- 配置
- 参考
- 社区资源
- 其他
- 为文档做出贡献
- 手动安装 Astro
- 升级到 Astro v4
- 升级到 Astro v3
- 升级到 Astro v2
- Legacy v0.x Upgrade Guide
- 从 Create React App(CRA)迁移
- 关于本教程
- 第一单元:前期准备
- 准备开发环境
- 创建你的第一个 Astro 项目
- 你的第一行 Astro 代码
- 创建在线代码仓库
- 将你的网站部署到网络
- 第二单元:页面
- 创建你的第一个 Astro 页面
- 编写你的第一篇 Markdown 博客文章
- 添加「关于你」的动态内容
- 给你的「关于」页面添加样式
- 应用全局样式
- 第三单元:组件
- 创建一个可重复使用的导航组件
- 创建社交媒体 footer
- 自己动手搭建导航 Header
- 编写你的第一个浏览器脚本
- 第四单元:布局
- 编写你的第一个布局
- 创建并传递数据到博客布局
- 布局结合,两全其美
- 第五单元 - Astro API
- 创建文章存档页
- 生成标签页面
- 编写标签索引页面
- 添加 RSS 订阅源
- 第六单元 - Astro 群岛
- 搭建你的第一个 Astro 岛屿
- 回到干燥的陆地。让你的博客从白天到黑夜,无需岛屿!
- 恭喜你!
- @astrojs/mdx
- 添加阅读时间
- 创建开发者工具栏应用
- @astrojs/alpinejs
- @astrojs/lit
- @astrojs/preact
- @astrojs/react
- @astrojs/solid-js
- @astrojs/svelte
- @astrojs/vue
- @astrojs/cloudflare
- @astrojs/netlify
- @astrojs/node
- @astrojs/vercel
- @astrojs/db
- @astrojs/markdoc
- @astrojs/partytown
- @astrojs/sitemap
- @astrojs/tailwind
- 使用流式处理来提升页面性能
- 从 Gatsby 迁移
- 从 Next.js 迁移
- 从 NuxtJS 迁移
- 从 Docusaurus 迁移到 Astro
- 从 Eleventy 迁移到 Astro
- 从 GitBook 迁移到 Astro
- 从Gridsome迁移到Astro
- 从 Hugo 迁移
- 从 Jekyll 迁移
- 从 Pelican 迁移
- 从 SvelteKit 迁移
- 从VuePress迁移
- 从 WordPress 迁移
- 状态共享
- Storyblok 与 Astro
- Contentful 与 Astro
- ButterCMS & Astro
- Builder.io & Astro
- Cosmic 与 Astro
- DatoCMS 与 Astro
- Front Matter CMS 与 Astro
- Ghost & Astro
- Hashnode & Astro
- Hygraph 与 Astro
- Keystatic & Astro
- Kontent.ai 与 Astro
- 无头模式的 Statamic 与 Astro
- Strapi 与 Astro
- Tina CMS 与 Astro
- Umbraco & Astro
- 无头(headless)模式的 WordPress 与 Astro
- ApostropheCMS 与 Astro
- Caisy & Astro
- CloudCannon与Astro
- Crystallize 与 Astro
- Decap CMS 与 Astro
- Directus 与 Astro
- KeystoneJS 与 Astro
- microCMS & Astro
- Payload CMS 与 Astro
- Prepr CMS & Astro
- Prismic & Astro
- Sanity & Astro
- Sitecore 体验管理器 & Astro
- Spinal & Astro
- 创作内容
- Firebase 与 Astro
- Supabase 与 Astro
- Turso 和 Astro
- Xata 与 Astro
- Appwrite & Astro
- 部署你的 Astro 站点至 Netlify
- 部署你的 Astro 站点至 Vercel
- 如何将你的 Astro 网站部署到 Deno
- 部署你的 Astro 站点至 GitHub Pages
- 部署你的 Astro 站点至 GitLab Pages
- 部署你的 Astro 站点至 Cloudflare Pages
- 将你的 Astro 网站部署到 AWS
- 将你的 Astro 网站通过 Flightcontrol 部署到 AWS
- 将你的 Astro 网站通过 SST 部署到 AWS
- 将你的 Astro 网站部署至 Google Cloud
- 部署你的 Astro 站点至 Google Firebase 托管
- 将你的 Astro 网站部署到 Heroku
- 将你的 Astro 网站部署到 Microsoft Azure
- 部署你的 Astro 站点至 Buddy
- 将你的 Astro 网站部署到 Edgio
- 将你的 Astro 站点部署到 Fly.io
- 将你的 Astro 网站部署到 Render
- 将你的 Astro 网站部署到 Stormkit
- 将你的 Astro 网站部署到 Surge
- 通过 Cleavr 部署你的 Astro 网站
- 将你的 Astro 站点部署到 Kinsta 应用托管
- 将你的 Astro 网站部署到 Space
- 将你的 Astro 站点部署到 Zeabur
- 将你的 Astro 网站部署到 Zerops
- 添加 RSS 摘要
- 安装一个 Vite 或 Rollup 插件
- 构建自定义图像组件
- 使用 API 路由构建表单
- 在 Astro 页面中构建 HTML 表单
- 在 Astro 中使用 Bun
- 调用服务器端点
- 校验验证码
- 用 Docker 来构建你的 Astro 网站
- 动态导入图片
- 为链接添加图标
- 添加 i18n 功能
- 添加最后修改时间
- 在 Astro 组件中共享状态
- 使用 Tailwind Typography 美化渲染后的 Markdown
- Unknown compiler error.
- Astro.redirect is not available in static mode.
- Astro.clientAddress is not available in current adapter.
- Astro.clientAddress cannot be used inside prerendered routes.
- Astro.clientAddress is not available in static mode.
- No static path found for requested path.
- Invalid type returned by Astro page.
- Missing value for client:media directive.
- No matching renderer found.
- No client entrypoint specified in renderer.
- Missing hint on client:only directive.
- Invalid value returned by a getStaticPaths path.
- Invalid entry inside getStaticPath's return value
- Invalid value returned by getStaticPaths.
- getStaticPaths RSS helper is not available anymore.
- Missing params property on getStaticPaths route.
- Invalid value for getStaticPaths route parameter.
- getStaticPaths() function required for dynamic routes.
- Invalid slot name.
- Cannot use Server-side Rendering without an adapter.
- No import found for component.
- Invalid prerender export.
- Invalid component arguments.
- Page number param not found.
- Image missing required "alt" property.
- Error while loading image service.
- Missing image dimensions
- Failed to retrieve remote image dimensions
- Unsupported image format
- Unsupported image conversion
- Prerendered dynamic endpoint has path collision.
- Expected src to be an image.
- Expected image options.
- Cannot set both densities and widths
- Image not found.
- Could not process image metadata.
- Image not found.
- Could not transform image.
- Unable to set response.
- The middleware didn't return a Response.
- The middleware returned something that is not a Response object.
- The endpoint did not return a Response.
- Value assigned to locals is not accepted.
- Astro.response.headers must not be reassigned.
- Can't load the middleware.
- Local images must be imported.
- Astro.glob() used outside of an Astro file.
- Astro.glob() did not match any files.
- A redirect must be given a location with the Location header.
- Invalid dynamic route.
- Could not find Sharp.
- Unknown Vite Error.
- Could not import file.
- Invalid glob pattern.
- Astro couldn't find the correct page to render
- The provided locale does not exist.
- Index page not found.
- You can't use the current function with the current strategy
- Prerendered routes aren't supported when internationalization domains are enabled.
- 启用了手动国际化路由但没有提供中间件。
- Astro can't render the route.
- Unhandled rejection
- i18n Not Enabled
- Route not found.
- Unknown CSS Error
- CSS Syntax Error
- Unknown Markdown Error.
- Failed to parse Markdown frontmatter.
- Invalid frontmatter injection.
- MDX integration missing.
- Unknown configuration error.
- Specified configuration file not found.
- Legacy configuration detected.
- Unknown CLI Error.
- Failed to generate content types.
- Unknown Content Collection Error.
- Content entry frontmatter does not match schema.
- Invalid content entry slug.
- Content Schema should not contain slug.
- Collection does not exist
- Content and data cannot be in same collection.
- Collection contains entries of a different type.
- Data collection entry failed to parse.
- Duplicate content entry slug.
- Actions must be used with server output.
- Unsupported transform in content config.
国际化(i18n)路由
Astro 的国际化(i18n)功能允许你将项目适配给国际受众。这个路由 API 帮助你生成、使用并验证你的多语言站点产生的 URL。
Astro 的 i18n 路由允许你带来你的多语言内容,并支持配置默认语言、计算相对页面 URL 以及接受访客浏览器提供的首选语言。你还可以基于每种语言指定回退语言,以便你的访客始终可以被引导至你站点上现有的内容。
路由逻辑
Astro 通过使用一个 中间件 来实现其路由逻辑。这个中间件函数被放置在 第一个位置,它会在最终执行自己的逻辑之前,等待来自任何额外中间件和每个页面路由的每一个 Response
。
这意味着来自你自己的中间件和页面逻辑的操作(例如重定向)首先被执行,你的路由被渲染,然后 i18n 中间件执行它自己的动作,比如验证一个本地化的 URL 是否对应一个有效的路由。
你也可以选择在 Astro 的 i18n 中间件之外,添加你自己的 i18n 逻辑,这样你可以在仍然能访问 astro:i18n
辅助函数的同时,对你的路由有更多的控制权。
配置 i18n 路由
在 i18n
配置对象中必须指定一个默认语言(defaultLocale
)和所有支持的语言列表(locales
)。此外,你还可以配置更具体的路由和回退行为,以匹配你期望的 URL。
import { defineConfig } from "astro/config"
export default defineConfig({
i18n: {
defaultLocale: "en",
locales: ["es", "en", "pt-br"],
}
})
创建本地化文件夹
根据语言组织你的内容文件夹中的本地化内容。在 src/pages/
内的任何位置创建单独的 /[locale]/
文件夹,Astro 的 基于文件的路由 将会在相应的 URL 路径下创建你的页面。
你的文件夹名称必须与 locales
中的项完全匹配。仅当你配置了 prefixDefaultLocale: true
来为你的默认语言显示一个本地化的 URL 路径时(例如 /zh-cn/about/),才包含一个为你的 defaultLocale
设定的本地化文件夹。
文件夹src
文件夹pages
- about.astro
- index.astro
文件夹es
- about.astro
- index.astro
文件夹pt-br
- about.astro
- index.astro
创建链接
配置了 i18n 路由后,你现在可以使用诸如 astro:i18n
模块 中提供的 getRelativeLocaleURL()
辅助函数来计算站点内页面的链接。这些生成的链接将始终提供正确的、本地化的路由,并且可以帮助你正确地使用或检查站点上的 URL。
你也可以选择手动编写链接。
src/pages/es/index.astro---
import { getRelativeLocaleUrl } from 'astro:i18n';
// defaultLocale 为 "es"
const aboutURL = getRelativeLocaleUrl("es", "about");
---
<a href="/get-started/">¡Vamos!</a>
<a href={getRelativeLocaleUrl('es', 'blog')}>Blog</a>
<a href={aboutURL}>Acerca</a>
routing
Astro 的内置基于文件的路由系统会根据你在 src/pages/
中的文件结构自动为你创建 URL 路由。
当你配置 i18n 路由时,这个文件结构的信息(以及生成的相应 URL 路径)将可供 i18n 辅助函数使用,以便它们能够为你的项目生成、使用和验证路由。许多这样的选项可以一起使用,以实现更多的自定义和按语言的灵活性。
你甚至可以选择手动实现自己的路由逻辑,以获得更大的控制权。
prefixDefaultLocale
添加于: astro@3.5.0
此路由选项定义了你的默认语言的 URL 是否应该使用语言前缀(例如 /en/about/
)。
所有非默认支持的语言将使用本地化前缀(例如 /fr/
或 /french/
),并且内容文件必须位于适当的文件夹中。此配置选项允许你指定你的默认语言是否也应该遵循本地化的 URL 结构。
此设置还决定了你的默认语言的页面文件必须存在于哪个位置(例如 src/pages/about/
或 src/pages/en/about
),因为文件结构和 URL 结构必须对所有语言都匹配。
"prefixDefaultLocale: false"
(默认):你的默认语言的 URL 不会有/[locale]/
前缀。所有其他语言都会有。"prefixDefaultLocale: true"
:所有 URL,包括你的默认语言,都会有/[locale]/
前缀。
prefixDefaultLocale: false
astro.config.mjsimport { defineConfig } from "astro/config"
export default defineConfig({
i18n: {
defaultLocale: "en",
locales: ["es", "en", "fr"],
routing: { prefixDefaultLocale: false
}
}
})
这是默认值。当你的默认语言的 URL 不会有 /[locale]/
前缀,并且你的默认语言的文件位于 src/pages/
的根目录时,设置这个选项:
文件夹src
文件夹pages
- about.astro
- index.astro
文件夹es
- about.astro
- index.astro
文件夹fr
- about.astro
- index.astro
src/pages/about.astro
将生成路由example.com/about/
src/pages/fr/about.astro
将生成路由example.com/fr/about/
prefixDefaultLocale: true
astro.config.mjsimport { defineConfig } from "astro/config"
export default defineConfig({
i18n: {
defaultLocale: "en",
locales: ["es", "en", "fr"],
routing: { prefixDefaultLocale: true
}
}
})
当所有路由在其 URL 中都有 /locale/
前缀,并且包括默认语言环境的所有页面内容文件都存在于一个本地化文件夹中时,设置这个选项:
文件夹src
文件夹pages
- index.astro // 注意:这个文件是必需的
文件夹en
- index.astro
- about.astro
文件夹es
- about.astro
- index.astro
文件夹pt-br
- about.astro
- index.astro
- 没有区域前缀的 URL(例如
example.com/about/
)将返回 404(未找到)状态码,除非你指定了一个回退策略。
redirectToDefaultLocale
添加于: astro@4.2.0
配置是否将由 src/pages/index.astro
生成的首页 URL (/
) 重定向到 /<defaultLocale>
。
设置 prefixDefaultLocale: true
也会在你的 routing
配置对象中自动设置 redirectToDefaultLocale: true
。默认情况下,必需的 src/pages/index.astro
文件将自动重定向到你的默认语言环境的首页。
你可以通过设置 redirectToDefaultLocale: false
来选择退出此行为。这允许你拥有一个存在于你配置的语言环境文件夹结构之外的站点首页。
manual
添加于: astro@4.6.0
当这个选项被启用时,Astro 将禁用其 i18n 中间件,以便你可以实现自己的自定义逻辑。其他的 routing
选项(例如 prefixDefaultLocale
)不能与 routing: "manual"
一起配置。
你将负责编写自己的路由逻辑,或者手动执行 Astro 的 i18n 中间件与你自己的逻辑一起。
astro.config.mjsimport { defineConfig } from "astro/config"
export default defineConfig({
i18n: {
defaultLocale: "en",
locales: ["es", "en", "fr"],
routing: "manual"
}
})
Astro 为你的中间件提供了辅助函数,以便你可以控制自己的默认路由、异常、回退行为、错误捕获等:redirectToDefaultLocale()
、notFound()
和 redirectToFallback()
:
import { defineMiddleware } from "astro:middleware";
import { redirectToDefaultLocale } from "astro:i18n"; // 在 `manual` 路由下可用的函数
export const onRequest = defineMiddleware(async (ctx, next) => {
if (ctx.url.startsWith("/about")) {
return next();
} else {
return redirectToDefaultLocale(302);
}
})
中间件函数
middleware
函数手动创建 Astro 的 i18n 中间件。这允许你扩展 Astro 的 i18n 路由,而不是完全替换它。
你可以将带有 路由选项的 middleware
与你自己的中间件结合使用,通过使用 sequence
工具来确定顺序运行 middleware
:
import { defineMiddleware, sequence } from "astro:middleware";
import { middleware } from "astro:i18n"; // Astro 自己的 i18n 路由配置
export const userMiddleware = defineMiddleware(async (ctx, next) => {
// 这个响应可能来自 Astro 的 i18n 中间件,它可能会返回一个 404
const response = await next();
// /about 页面是一个例外,我们想要渲染它
if (ctx.url.startsWith("/about")) {
return new Response("关于页面", {
status: 200
});
} else {
return response;
}
});
export const onRequest = sequence(
userMiddleware,
middleware({
redirectToDefaultLocale: false,
prefixDefaultLocale: true
})
)
domains
添加于: astro@4.9.0
新
这个路由选项允许你为使用 @astrojs/node
或 @astrojs/vercel
适配器并配置了 site
的服务端渲染项目,按语言自定义你的域名。
添加 i18n.domains
来将你支持的任何 locales
映射到自定义 url:
import { defineConfig } from "astro/config"
export default defineConfig({ site: "https://example.com", output: "server", // 必须,没有预渲染的页面 adapter: node({ mode: 'standalone', }),
i18n: {
defaultLocale: "en",
locales: ["es", "en", "fr", "ja"],
routing: {
prefixDefaultLocale: false
}, domains: { fr: "https://fr.example.com", es: "https://example.es" } }})
所有未映射的 locales
将遵循你的 prefixDefaultLocales
配置。然而,即使这个值为 false
,你的 defaultLocale
的页面文件也必须存在于一个本地化文件夹中。对于上面的配置,需要一个 /en/
文件夹。
根据上述配置:
- 文件
/fr/about.astro
将创建 URLhttps://fr.example.com/about
。 - 文件
/es/about.astro
将创建 URLhttps://example.es/about
。 - 文件
/ja/about.astro
将创建 URLhttps://example.com/ja/about
。 - 文件
/en/about.astro
将创建 URLhttps://example.com/about
。
上述 URL 也将通过 getAbsoluteLocaleUrl()
和 getAbsoluteLocaleUrlList()
函数返回。
fallback
Astro 的 i18n 路由允许你配置一个回退路由策略。当一个页面在某种语言下不存在时(例如,一个尚未翻译的页面),你可以基于每种语言将用户从一个语言环境重定向到另一个语言环境,而不是显示 404 页面。这在你还没有为每个路由准备好页面,但仍想为访客提供一些内容时非常有用。
例如,下面的配置为任何缺失的 fr
路由设置 es
作为回退语言环境。这意味着,当 src/pages/fr/my-page.astro
不存在时,访问 example.com/fr/my-page/
的用户将被重定向到 example.com/es/my-page/
并显示那里的内容,而不是被带到 404 页面。
import { defineConfig } from "astro/config"
export default defineConfig({
i18n: {
defaultLocale: "en",
locales: ["es", "en", "fr"], fallback: { fr: "es" }
}
})
Astro 会确保 src/pages/es/
中的每个页面都在 src/pages/fr
中构建一个对应页面。如果页面尚未存在,那么将创建一个页面,并将其重定向到相应的 es
路由。
自定义语言环境路径
除了将你的网站支持的 locales
定义为字符串(例如 “en”, “pt-br”)之外,Astro 还允许你将任意数量的浏览器识别的语言 codes
映射到自定义的 URL path
上。虽然语言环境可以是任何格式的字符串,只要它们与你的项目文件夹结构相对应,但 codes
必须遵循浏览器接受的语法。
向 locales
数组传递一个对象,并使用 path
键来定义自定义的 URL 前缀,使用 codes
来指示映射到此 URL 的语言。在这种情况下,你的 /[locale]/
文件夹名称必须与 path
的值完全匹配,而你的 URL 将使用 path
的值来生成。
如果你支持一个语言的多个变体(例如 "fr"
、"fr-BR"
和 "fr-CA"
),并且你希望所有这些变体都映射到同一个 URL /fr/
下,或者甚至完全自定义它(例如 /french/
),这将非常有用:
import { defineConfig } from "astro/config"
export default defineConfig({
i18n: {
defaultLocale: "en", locales: ["es", "en", "fr"], locales: ["es", "en", { path: "french", // 不包含斜杠 codes: ["fr", "fr-BR", "fr-CA"] }],
routing: {
prefixDefaultLocale: true
}
}
})
当使用来自 astro:i18n
虚拟模块 的函数根据你的配置计算有效的 URL 路径时(例如 getRelativeLocaleUrl()
),请使用 path
作为 locale
的值。
限制
此功能有一些限制:
- 必须设置
site
选项。 output
选项必须设置为"server"
。- 不能有任何单独的预渲染页面。
- 不支持适配器功能
functionPerRoute
。
Astro 依赖以下头信息以支持此功能:
X-Forwarded-Host
和Host
。Astro 会优先使用前者,如果不存在,则尝试后者。- 服务端请求的
X-Forwarded-Proto
和URL#protocol
。
请确保你的服务器代理/托管平台能够提供这些信息。获取这些头信息失败将导致一个 404(状态码)页面。
浏览器语言检测
Astro 的 i18n 路由允许你在按需渲染的页面中访问两个用于浏览器语言检测的属性:Astro.preferredLocale
和 Astro.preferredLocaleList
。所有页面,包括静态预渲染页面,都可以访问 Astro.currentLocale
。
这些属性结合了浏览器的 Accept-Language
头部信息和你的 locales
(字符串或 codes
),以自动遵循访问者的首选语言。
Astro.preferredLocale
: 如果访客的浏览器首选语言环境包含在你的locales
数组中,Astro 可以为你的访客计算一个首选语言环境。如果没有这样的匹配存在,此值为 undefined。Astro.preferredLocaleList
: 一个包含了浏览器请求并且你的网站支持的所有语言环境的数组。这将产生一个你的网站和访客之间所有兼容语言的列表。如果在你的locales
数组中找不到浏览器请求的任何语言,该值为[]
。如果浏览器没有指定任何首选语言,则此值将是i18n.locales
。Astro.currentLocale
: 从当前 URL 计算的语言环境,使用你的locales
配置指定的语法。如果 URL 不包含/[locale]/
前缀,则该值将默认为i18n.defaultLocale
。
为了成功匹配访客的偏好,请使用与浏览器使用的模式相同的模式提供你的 codes
。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论