路由
Astro 使用基于文件的路由,它根据项目 src/pages
目录中的文件结构来生成你的构建链接。
页面之间的导航
段落标题 页面之间的导航Astro 使用标准 HTML <a>
元素 在路由之间导航。 没有提供特定框架的 <Link>
组件。
静态路由
段落标题 静态路由src/pages
目录中的 .astro
页面组件以及 Markdown 和 MDX 文件(.md
,.mdx
)将自动作为网站页面。每个页面的路由对应于它在 src/pages/
目录中的路径和文件名。
Astro 项目没有单独的路由配置!当你在 src/pages
目录新增文件时,会自动生成一个新的路由。在静态生成中,你可以使用 build.format
配置项自定义文件输出格式。
动态路由
段落标题 动态路由Astro 页面文件可以在其文件名中指定动态路由参数以生成多个匹配页面。
例如,src/pages/authors/[author].astro
可以为你博客上的每一位作者生成一个简介页面,而 author
将作为一个你可以从页面内部访问的 参数 。
在 Astro 默认的静态输出模式中,这些页面是在构建时生成的,因此你必须预设对应文件的 author
列表。而在 SSR 模式下,将根据请求为任何匹配的路由生成一个页面。
静态 (SSG) 模式
段落标题 静态 (SSG) 模式因为必须在构建时确定所有路由,所以动态路由必须导出一个 getStaticPaths()
,它返回一个具有 params
属性的对象数组。数组中的每一个对象都会生成相应的路由。
[dog].astro
在其文件名中定义一个 dog
参数,则 getStaticPaths()
返回的这些对象的 params
中必须包含 dog
。
然后页面可以使用 Astro.params
访问该参数。
这将生成三个页面: /dogs/clifford
、/dogs/rover
和 /dogs/spot
,每个页面显示相应的狗名。
文件名可以包含多个参数,这些参数必须都包含在 getStaticPaths()
的 params
对象中:
这将生成 /en-v1/info
和 /fr-v2/info
路由。
参数也可以包含在路径的单独部分中。例如, src/pages/[lang]/[version]/info.astro
文件与上面相同的 getStaticPaths()
将生成路由 /en/v1/info
和 /fr/v2/info
。
getStaticPaths()
的内容。
剩余参数
段落标题 剩余参数如果你的URL路由需要更加灵活,你可以在 .astro
文件名中使用一个 剩余参数([...path]
),去匹配任何深度的文件路径。
这将生成 /sequences/one/two/three
、 /sequences/four
和 /sequences
。(将剩余参数设置为 undefined
允许它匹配顶级页面。)
剩余参数可以与 其他命名参数 一起使用。例如, GitHub 的文件查看器可以用以下动态路由表示:
在这个示例中,对 /withastro/astro/tree/main/docs/public/favicon.svg
的请求将拆分为以下命名参数:
示例:多级动态页面
段落标题 示例:多级动态页面在下面的示例中, 剩余参数([...slug]
)和 getStaticPaths()
的 props
为不同深度的 slug 生成页面。
服务器(SSR)模式
段落标题 服务器(SSR)模式在 SSR (EN) 模式下,动态路由以相同的方式定义:在文件名中包含 [param]
或 [...path]
以匹配任意字符串或路径。但是由于不再提前构建路由,页面将提供给任何匹配的路由。由于这些路由不是“静态”的,因此不应使用 getStaticPaths
。
该页面将为任意的 resource
和 id
提供服务: resources/users/1
、 resources/colors/blue
等。
修改 [...slug]
示例用于SSR
段落标题 修改 [...slug] 示例用于SSR由于 SSR 页面无法使用 getStaticPaths()
,因此无法接收 props。可以通过在对象中查找 slug
参数的值,将 前面的示例 调整为 SSR 模式。如果路由位于根目录(“/”),则 slug 参数为 undefined
。如果对象中不存在该值,将重定向到 404 页面。
重定向
段落标题 重定向有时你需要为你的读者重定向到一个新的页面,可能由于你的网站结构发生了永久性的变动,又或者是作为响应动作(比如从登录到身份验证的过程)。
你可以在你的 Astro 配置中定义规则来将用户 永久重定向到已移动的页面。或者,根据用户的使用情况,动态地将用户重定向。
配置重定向
段落标题 配置重定向
Added in:
astro@2.9.0
在你的 Astro 配置中,你可以使用 redirects
值来指定永久重定向的映射关系。对于大多数重定向而言,通常是将旧路由映射到新路由:
这些重定向遵循 与基于文件路由相同的优先级规则,并且优先级将会始终低于现有项目中同名的页面文件。例如:如果你的项目包含 src/pages/old-page.astro
文件,那么 /old-page
将不会重定向到 /new-page
。
只要新旧路由都包含相同的参数,就可以使用动态路由,例如:
使用 SSR(服务器端渲染)或者静态适配器,你还可以将对象作为值提供,除了新的 destination
端点指向之外,还可以指定 status
状态码:
在运行 astro build
时,默认情况下,Astro 将输出带有 meta refresh 标签的 HTML 文件。支持的适配器将会使用托管服务器的配置文件写入重定向信息。
状态码默认为 301
。如果构建为 HTML 文件,则服务器不会使用状态码。
动态重定向
段落标题 动态重定向在全局的 Astro
对象上,Astro.redirect
方法允许你动态地重定向到另一个页面。例如,你可以在检查用户是否已登录(通过从 Cookie 中获取其会话)之后执行此操作。
重写
段落标题 重写
Added in:
astro@4.13.0
重写允许你提供不同的路由,而无需将浏览器重定向到不同的页面。浏览器将在 URL 栏中显示原始地址,但实际上会显示 Astro.rewrite()
提供的 URL 的内容。
对于永久性移动的内容,或者将用户重定向到具有新 URL 的不同页面(例如登录后的用户仪表盘),请使用 重定向。
重写对于在不同路径(例如 /products/shoes/men/
和 /products/men/shoes/
)显示相同内容非常有用,而无需维护两个不同的源文件。
重写对于用户体验和 SEO 也非常有用。它允许你显示需要将访问者重定向到其他页面或返回 404 状态的内容。 重写的一个常见用途是为语言的不同变体显示相同的本地化内容。
以下示例使用重写来在访问 /es-CU/
(古巴西班牙语)URL 路径时渲染 /es/
版本的页面。当访问者导航到 /es-cu/articles/introduction
URL 时,Astro 将渲染由文件 src/pages/es/articles/introduction.astro
生成的内容。
使用 context.rewrite()
在你的端点文件中重定向到不同的页面:
如果传递给 Astro.rewrite()
的 URL 引发运行时错误,Astro 将在开发中显示错误覆盖层,并在生产中返回 500 状态码。如果你的项目中不存在该 URL,则将返回 404 状态码。
你可以有意创建一个重写来渲染你的 /404
页面,例如,以指示你的电子商店中的产品不再可用:
你也可以根据 HTTP 响应状态有条件地重写,例如在访问不存在的 URL 时显示站点上的某个页面:
显示指定重写路径的内容之前,Astro.rewrite()
函数将触发一个新的完整渲染阶段。这将为新的路由/请求重新执行任何中间件。
Astro.rewrite()
API 参考
路由优先级顺序
段落标题 路由优先级顺序可能有多个已定义的路由试图构建相同的 URL 路径。例如,下面所有这些路由都有可能构建 /posts/create
:
文件夹src/pages/
- […slug].astro
文件夹posts/
- create.astro
- [page].astro
- [pid].ts
- […slug].astro
Astro 需要知道哪个路由应该被用来构建页面。为此,它会按照以下规则按顺序对它们进行排序:
- Astro 预留路由
- 路径段更多的路由将优先于不太具体的路由。在上面的例子中,所有在
/posts/
下的路由优先于根目录的/[...slug].astro
。 - 没有路径参数的静态路由将优先于动态路由。例如,
/posts/create.astro
优先于示例中的所有其他路由。 - 使用命名参数的动态路由优先于剩余参数。例如,
/posts/[page].astro
优先于/posts/[...slug].astro
。 - 预渲染的动态路由优先于服务器动态路由。
- 端点优先于页面。
- 基于文件的路由优先于重定向。
- 如果以上规则都无法决定顺序,路由将根据你的 Node 安装的默认语言环境按字母顺序排序。
鉴于上面的示例,下面用几个例子,说明这些规则如何匹配请求的 URL 与用于建立 HTML 的路由。
pages/posts/create.astro
- 将只构建/posts/create
pages/posts/[pid].ts
- 将构建/posts/abc
、/posts/xyz
等,但不包括/posts/create
pages/posts/[page].astro
- 将构建/posts/1
、/posts/2
等,但不包括/posts/create
、/posts/abc
以及/posts/xyz
pages/posts/[...slug].astro
- 将构建/posts/1/2
、/posts/a/b/c
等,但不包括/posts/create
、/posts/1
、/posts/abc
等pages/[...slug].astro
- 将构建/abc
、/xyz
、/abc/xyz
等,但不包括/posts/create
、/posts/1
、/posts/abc
等
预留路由
段落标题 预留路由内部路由优先于任何用户定义或集成定义的路由,因为 Astro 功能需要它们才能工作。以下是 Astro 的预留路由:
_astro/
: 向客户端提供所有静态资源,包括 CSS 文档、打包的客户端脚本、优化后的图像和任何 Vite 资源。_server_islands/
: 为延迟渲染的 服务器群岛 动态组件提供服务。_actions/
: 服务于任何已定义的 action。
分页
段落标题 分页Astro 支持内置分页,用于需要分割成多个页面的大量数据。Astro 会生成常见的分页属性,包括上一页/下一页链接、总页数等。
分页的路由名应该使用与标准动态路由一样的 [bracket]
语法。例如,文件名 /astronauts/[page].astro
将生成 /astronauts/1
、/astronauts/2
等路由,其中 [page]
是生成的页码。
你可以用 paginate()
函数根据数组值生成这些页面:
将生成以下两个页面,每页 2 项:
/astronauts/1
- 第一页显示“Neil Armstrong”和“Buzz Aldrin”/astronauts/2
- 第二页显示“Sally Ride”和“John Glenn”
page
属性
段落标题 page 属性当你使用 paginate()
函数时,每个页面将通过 page
传递数据。page
有很多有用的属性,你可以使用它们来构建页面以及页面之间的链接:
以下示例,展示了当前页面相对于其他相关页面的导航链接:
嵌套分页
段落标题 嵌套分页分页的一个更高级的用例是嵌套分页。当分页与其他动态路由参数相结合时,你可以使用嵌套式分页和一些属性或标签来将分页进行分类。
例如,如果你想通过一些标签来分组你的分页的 Markdown 帖子,你可以通过创建一个 /src/pages/[tag]/[page].astro
的页面来使用嵌套分页,该页面将匹配以下链接。
/red/1
(tag=red)/red/2
(tag=red)/blue/1
(tag=blue)/green/1
(tag=green)
嵌套分页的工作原理是使用 getStaticPaths()
返回每个分组的 paginate()
结果数组。
在下面的例子中,我们将实现嵌套分页来建立上面列出的URL。
排除页面
段落标题 排除页面你可以通过在文件名前加上下划线(_
)来排除页面或目录的构建。带有 _
前缀的文件不会被路由识别,也不会被放入 dist/
目录。
你可以使用它来暂时禁用页面,并将测试、工具函数和组件放在与其相关页面同一个文件夹中。
在这个例子中,只有 src/pages/index.astro
和 src/pages/posts/post1.md
将被构建为页面路由和 HTML 文件。
文件夹src/pages/
文件夹_hidden-directory/
- page1.md
- page2.md
- _hidden-page.astro
- index.astro
文件夹posts/
- _SomeComponent.astro
- _utils.js
- post1.md