立即迁移到 Netlify

Netlify 宣布 Gatsby Cloud 的下一次迭代。 了解更多

文件系统路由 API

示例

  • 使用文件系统路由 API

当您想创建动态页面时,例如为您的博客创建单独的博文页面,请使用文件系统路由 API。

您应该能够通过这个基于文件的 API 完成大多数常见任务。如果您想更精细地控制页面创建,则应使用 createPages API。

Gatsby 的 GraphQL 数据层 中的集合可以创建动态页面,并且可以创建 仅客户端路由

完整的示例,展示了所有选项,可以在 Gatsby 的示例文件夹 中找到。

集合路由

设想一个 Gatsby 项目,它从 product.yaml 文件和多个 Markdown 博文中提取数据。在构建时,Gatsby 会自动 推断 字段,并为这两种类型(ProductMarkdownRemark)创建多个 节点

要创建集合路由,请在文件名中使用花括号({ })来表示动态 URL 段,这些段与节点中的字段相关。这里有一些示例:

  • src/pages/products/{Product.name}.js 将生成一个像 /products/burger 这样的路由
  • src/pages/products/{Product.fields__sku}.js 将生成一个像 /products/001923 这样的路由
  • src/pages/blog/{MarkdownRemark.parent__(File)__name}.js 将生成一个像 /blog/learning-gatsby 这样的路由

Gatsby 为集合路由中的每个节点创建一个页面。因此,如果您有三个作为博文的 markdown 文件,Gatsby 将从集合路由创建这三个页面。当您添加和删除 markdown 文件时,Gatsby 会相应地添加和删除页面。

集合路由可以为任何 GraphQL 数据类型创建。在 Gatsby 中创建新的集合路由的过程是添加一个源插件,使用 GraphiQL 识别类型和字段来构建路由文件名,然后编写路由组件。

语法(集合路由)

使用集合路由时,有一些通用的语法要求:

  • 文件路径的动态段必须以花括号({ })开头和结尾。
  • 类型是区分大小写的(例如 MarkdownRemarkcontentfulMyContentType)。请在 GraphiQL 中检查正确的名称。
  • 动态段必须同时包含类型和字段,例如 {Type.field}{BlogPost.slug}

嵌套路由

您可以在路径中使用动态段多次。例如,您可能希望将产品名称嵌套在其产品类别中。例如:

  • src/pages/products/{Product.category}/{Product.name}.js 将生成一个像 /products/toys/fidget-spinner 这样的路由
  • src/pages/products/{Product.category}/{Product.name}/{Product.color}.js 将生成一个像 /products/toys/fidget-spinner/red 这样的路由

字段语法

点表示法

使用 . 来表示您想访问节点上的某个字段。

src/pages/products/{Product.name}.js 将生成以下查询:

下划线表示法

使用 __(双下划线)来表示您想访问节点上的嵌套字段。

src/pages/products/{Product.fields__sku}.js 将生成以下查询:

您可以任意嵌套深度,例如 src/pages/products/{Product.fields__date__createdAt}.js 将生成以下查询:

括号表示法

使用 ( ) 来表示您想访问一个 GraphQL 联合类型。这通常对于 Gatsby 为您创建的类型是可能的。例如,MarkdownRemark 总是有一个 File 作为父类型,因此您也可以访问 File 节点中的字段。您也可以多层嵌套,例如 src/pages/blog/{Post.parent__(MarkdownRemark)__parent__(File)__name}.js

src/pages/blog/{MarkdownRemark.parent__(File)__name}.js 将生成以下查询:

集合路由组件

集合路由组件会接收两个动态变量:每个页面的节点的 id 和 URL 路径作为 params。params 会作为 props.params 传递给组件,id 会作为 props.pageContext.id 传递。

两者都会作为变量传递给组件的 GraphQL 查询,因此您可以查询节点的字段。页面查询(包括变量的使用)将在 使用 GraphQL 查询页面数据 中更深入地进行解释。

例如:

对于页面 src/pages/{Product.name}/{Product.coupon}.js,在 {Product.coupon}.js 中,您将可以访问 props.params.nameprops.params.coupon

如果您需要为集合中的某些节点创建页面(例如,过滤掉类型为 "Food" 的产品)或自定义传递给查询的变量,则应改用 createPages API,因为文件系统路由 API 目前不支持此功能。

路由和链接

Gatsby 会对从集合页面创建的每个路由进行“slugify”(通过使用 sindresorhus/slugify)。换句话说:如果您有一个名为 src/pages/wholesome/{Animal.slogan}.js 的路由,其中 sloganI ♥ Dogs,则最终 URL 将是 /wholesome/i-love-dogs。Gatsby 会将字段转换为人类可读的 URL 格式,同时去除无效字符。您可以为 src/pages 路径调整 gatsby-plugin-page-creator 来配置 slugify

当您想链接到集合路由页面时,可能并不总是清楚如何从头开始构建 URL。

为了解决这个问题,Gatsby 会自动为集合页面使用的每个类型添加一个 gatsbyPath 字段。 gatsbyPath 字段必须接受一个 filePath 参数,它试图解析该文件路径。这是必需的,因为一种类型可能被用于多个集合页面。

使用 filePath 参数时,有一些通用的语法要求:

  • 路径必须是绝对路径(以 / 开头)。
  • 您必须省略文件扩展名。
  • 您必须省略 src/pages 前缀。
  • 您的路径不得包含 index

gatsbyPath 示例

假设 Product 类型在两个页面中使用:

  • src/pages/products/{Product.name}.js
  • src/pages/discounts/{Product.name}.js

如果您想从主页链接到 products/{Product.name}discounts/{Product.name} 路由,您将拥有一个如下所示的组件:

通过使用 别名,您可以多次使用 gatsbyPath

创建仅客户端路由

如果您有不在 Gatsby 中存在的动态数据,请使用 仅客户端路由。这可能是一个用户设置页面,或其他在构建时 Gatsby 未知的动态内容。在这些情况下,您通常会创建一个带有或多个动态段的路由,以便从服务器查询数据来渲染您的页面。

语法(仅客户端路由)

您可以在文件路径中使用方括号([ ])来标记 URL 的任何动态段。例如,为了编辑用户,您可能需要一个像 /user/:id 这样的路由来获取传递到 URL 的任何 id 的数据。

  • src/pages/users/[id].js 将生成一个像 /users/:id 这样的路由
  • src/pages/users/[id]/group/[groupId].js 将生成一个像 /users/:id/group/:groupId 这样的路由

Splat 路由

Gatsby 还支持 splat(或通配符)路由,这些路由将匹配 任何 在 splat 之后的内容。这些不太常见,但仍然有其用途。在文件路径中使用方括号中的三个点([...])可以将页面标记为 splat 路由。您还可以通过在三个点后添加名称来命名您的页面接收的参数([...myNameKey])。

例如,假设您正在从 S3 渲染图像,并且 URL 实际上是 AWS 资源的键。以下是如何创建您的文件:

  • src/pages/image/[...].js 将生成一个像 /image/* 这样的路由。 * 在您的页面的接收属性中以 * 的键名访问。
  • src/pages/image/[...awsKey].js 将生成一个像 /image/*awsKey 这样的路由。 *awsKey 在您的页面的接收属性中以 awsKey 的键名访问。

Splat 路由可能无法与常规仅客户端路由位于同一目录中。

示例

文件名中的动态段(方括号之间的部分)将被填充并作为 props.params 对象提供给您的组件。例如:

config 函数

在文件系统路由模板中,您可以导出一个名为 config 的异步函数。您可以使用此函数来:

在您的模板内

当您导出一个异步 config 函数时,Gatsby 会评估返回的对象,并可以选择性地运行在外层函数中定义的任何 GraphQL 查询。您不能在内层函数中运行 GraphQL 查询。

params 参数是一个包含 URL 路径的对象,请参阅 上面的说明

config 的内层函数可以返回一个只包含一个键的对象:

  • defer:一个布尔值,表示页面是否应标记为延迟。

请阅读 延迟静态生成指南 以查看真实示例。

示例用例

请查看 route-api 示例 以获取更多详细信息。

集合路由 + 回退

通过结合使用集合路由和仅客户端路由,您可以在用户尝试访问集合路由中不存在(尚未)的集合项的 URL 时,创建无缝的体验。考虑这两个文件路径:

  • src/pages/products/{Product.name}.js(集合路由)
  • src/pages/products/[name].js(仅客户端路由,回退)

集合路由将在 构建 时创建所有可用的产品页面。如果您添加了一个新的产品要链接,但只定期构建您的站点,您将需要一个回退。通过使用仅客户端路由作为回退,您可以在重新构建站点之前,在客户端加载产品的必要信息。

同样,回退页面也可用于产品不存在时,您希望显示一些有用的信息(例如 404 页面)。

使用一个模板创建多个路由

通过将路由的模板/视图放入可重用组件中,您可以显示相同的信息在不同的路由下。看这个例子:

您想显示产品信息,该信息可以通过名称和 SKU 访问,但具有相同的样式。首先创建两个文件路径:

  • src/pages/products/{Product.name}.js
  • src/pages/products/{Product.meta__sku}.js

src/view/product-view.js 创建一个接收 product prop 的视图组件。在两个集合路由中使用该组件,例如:

您可以将相同的代码复制到 src/pages/products/{Product.meta__sku}.js 文件中。

纯粹的仅客户端应用

如果您希望您的 Gatsby 应用 100% 仅在客户端运行,您可以将文件放在 src/pages/[...].js 来捕获所有请求。有关更多详细信息,请参阅 client-only-paths 示例

立即开始构建,在 Netlify!
在 GitHub 上编辑此页面
©2025Gatsby, Inc.