You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修复Next.js 15动态路由预渲染错误

Next.js 15动态路由预渲染错误解决方案

问题背景

我有一个未使用use cache的动态路由页面,代码如下:

// /search/[query]/page.tsx 
import { Suspense } from "react";

import SearchQuery from "@/components/Search/Query";
import { Skeleton } from "@/components/ui/skeleton";

export default async function SearchPage({
    params,
}: {
    params: Promise<{ query: string }>;
}) {
    const queries = params.then(param => param.query);

    return (
        <Suspense fallback={<Skeleton className="h-[140px] w-full" />}>
            {/* @ts-expect-error Async Server Component */}
            <SearchQuery queries={queries} />
        </Suspense>
    );
}

构建项目时触发预渲染错误:

Route "/search/[query]": A component accessed data, headers, params, searchParams, or a short-lived cache without a Suspense boundary nor a "use cache" above it. We don't have the exact line number added to error messages yet but you can see which component in the stack below.

即便添加use cache,甚至使用Next.js官方示例代码,仍会抛出相同错误:

export default async function Page({
  params,
}: {
  params: Promise<{ slug: string }>
}) {
  const { slug } = await params
  return <h1>Blog Post: {slug}</h1>
}

我的next.config.mjs配置:

import path from "path";

const __dirname = path.resolve();

/** @type {import('next').NextConfig} */
const nextConfig = {
    experimental: {
        reactCompiler: true,
        dynamicIO: true,
    },
    sassOptions: {
        includePaths: [path.join(__dirname, "components")],
        prependData: `@use "@/assets/mixins" as *;`,
    },
    transpilePackages: ["@web3-name-sdk/core"],
};

export default nextConfig;

使用的Next.js版本为^15.1.1-canary.7。

原因分析

该错误由开启experimental.dynamicIO实验特性导致。Next.js 15预览版中,dynamicIO会改变服务器组件处理动态参数(如params)的逻辑,强制要求所有访问动态数据的操作必须包裹在use cache或Suspense边界内,但当前canary版本存在兼容性bug,即便按要求操作仍会触发错误。

解决方案

方案一:临时关闭dynamicIO实验特性

在next.config.mjs中移除dynamicIO: true配置,这是最直接的修复方式:

// 修改后的nextConfig
const nextConfig = {
    experimental: {
        reactCompiler: true,
        // 移除dynamicIO配置
    },
    sassOptions: {
        includePaths: [path.join(__dirname, "components")],
        prependData: `@use "@/assets/mixins" as *;`,
    },
    transpilePackages: ["@web3-name-sdk/core"],
};

方案二:规范使用use cache并调整参数传递逻辑

确保在页面组件顶部声明use cache,且在页面内先await拿到params的实际值,再传递给子组件:

// /search/[query]/page.tsx 
import { Suspense } from "react";

import SearchQuery from "@/components/Search/Query";
import { Skeleton } from "@/components/ui/skeleton";

// 在组件最顶部声明use cache
use cache;

export default async function SearchPage({
    params,
}: {
    params: Promise<{ query: string }>;
}) {
    // 直接await获取实际参数值,避免传递Promise给子组件
    const { query: queries } = await params;

    return (
        <Suspense fallback={<Skeleton className="h-[140px] w-full" />}>
            <SearchQuery queries={queries} />
        </Suspense>
    );
}

方案三:升级到最新Next.js 15预览版

由于使用的是canary版本,该bug可能已在后续更新中修复,执行以下命令升级:

npm install next@latest-canary
# 或使用yarn/pnpm
yarn add next@latest-canary
pnpm add next@latest-canary

内容的提问来源于stack exchange,提问作者oynozan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 11:58:13