Skip to content

动态路由静态化

在 Next.js 中,动态路由静态化是指为具有动态参数的页面在构建时生成静态版本。这可以通过 getStaticPathsgetStaticProps 函数实现。这两个函数允许你在构建时根据不同的参数预渲染页面,并且可以结合增量静态再生成(ISR)来按需更新这些页面。

动态路由静态化的步骤

假设我们正在构建一个博客网站,其中每篇文章都有一个唯一的 ID。我们希望在构建时为每篇文章生成静态 HTML 页面,并能够在文章内容更新时重新生成这些页面。

1. 创建动态路由文件

首先,在 pages/posts/[id].js 文件中定义你的动态路由页面。

jsx
// pages/posts/[id].js
import { useRouter } from "next/router";

export async function getStaticProps({ params }) {
  // 假设 fetchPostById 是一个异步函数,用来获取指定ID的文章数据
  const post = await fetchPostById(params.id);

  return {
    props: {
      post,
    },
    revalidate: 60, // 设置为60秒后重新验证并可能更新此页面
  };
}

export async function getStaticPaths() {
  // 假设 fetchAllPostsIds 是一个异步函数,返回所有文章的ID列表
  const posts = await fetchAllPostsIds();

  const paths = posts.map((post) => ({
    params: { id: post.id.toString() }, // 必须与动态参数匹配
  }));

  return { paths, fallback: false }; // 如果未预渲染的路径被访问,则返回404页面
}

function Post({ post }) {
  const router = useRouter();
  if (router.isFallback) {
    return <div>加载中...</div>;
  }

  return (
    <div>
      <h1>{post.title}</h1>
      <p>{post.content}</p>
    </div>
  );
}

export default Post;

在这个例子中:

  • getStaticProps:用于获取每个文章的具体数据,并将这些数据作为属性传递给组件。通过设置 revalidate 参数,可以启用增量静态再生成(ISR),使得页面可以在一段时间后自动更新。
  • getStaticPaths:定义了哪些路径应该被预渲染。这里我们遍历所有文章的 ID,并为每个 ID 创建一个路径对象。

2. 处理未预先生成的路径

如果设置了 fallback: true'blocking',则对于那些没有在构建时预先生成的路径,Next.js 将尝试在首次请求时生成这些页面。这对于拥有大量动态路径的应用非常有用,因为它不需要在构建时生成所有可能的页面。

  • fallback: true:当访问未预先生成的路径时,会先显示一个“加载中”的状态,然后生成页面并在客户端渲染。
  • fallback: 'blocking':当访问未预先生成的路径时,服务器会阻塞响应直到页面生成完成,然后直接展示最终的页面。

3. 数据获取示例

为了完整起见,这里是一个简单的数据获取函数的例子:

javascript
async function fetchPostById(id) {
  const res = await fetch(`https://api.example.com/posts/${id}`);
  const data = await res.json();
  return data;
}

async function fetchAllPostsIds() {
  const res = await fetch("https://api.example.com/posts/ids");
  const data = await res.json();
  return data;
}

这些函数应根据你实际的数据源进行调整。

通过这种方式,你可以轻松地为动态路由实现静态化,同时利用 ISR 的功能确保页面内容始终保持最新。这种方法不仅提高了性能和 SEO 效果,还简化了开发流程,使得管理和扩展大型站点变得更加容易。

Released under the MIT License.