Next.js 16 PPR:/api/og路由在每次构建时都会输出“需要退出预渲染”

前端开发 2026-07-08

我在Next.js 16项目中启用了部分预渲染(PPR),方法是通过在所有页面注释掉export const dynamic = "force-dynamic" 并在next.config.ts中加入cacheComponents: true。构建成功,所有页面都正确进行预渲染,但在next build过程中会把这个日志打印两次:

OpenGraph image generation failed: Error: Route /api/og needs to bail out of prerendering at this point because it used request.url. at R (app\api\og\route.tsx:60:46)
  58 | ...port async function GET(request: NextRequest) {
  59 | ...try {
> 60 | ...  const { searchParams } = new URL(request.url);
     |       
                                        ^

该路由在处理中会用request.url读取搜索参数,并用request.headers读取动态主机名,因此无法进行静态预渲染。该错误不会导致构建失败,但会使输出变得混乱。
我之前在这个路由上设置了export const runtime = "edge",但已移除。由于这会破坏PPR的初衷,我也不想再添加export const dynamic = "force-dynamic"。

我尝试过:

  • 移除export const runtime = "edge" —— 没有变化
  • 将读取搜索参数的逻辑移动到处理程序内部(本来就在里面)——没有变化
  • 使用try/catch包裹(本来就是这样)——这只是一个预渲染中止,而不是运行时错误

问题:

  1. 是否有办法在不使用force-dynamic的情况下,显式将单个API路由排除在PPR之外?
  2. 这只是一个无害的日志,可以被抑制,还是表示有问题?
  3. OG图像路由是否应放在一个单独的路由组中,在布局层设置export const dynamic = "force-dynamic"?

环境:

  • Next.js 16.2.6
  • next.config.ts中 cacheComponents: true
  • 全局启用了PPR(没有anywhere使用force-dynamic)
  • 路由:app/api/og/route.tsx

解决方案

在我的Next.js配置中设置experimental.hideLogsAfterAbort: true。

next.config.ts
const nextConfig: NextConfig = {
cacheComponents: true,
experimental: {
hideLogsAfterAbort: true,
other experiments...
  },
 };
export default nextConfig;

为什么会这样: 根本原因是cacheComponents: true,而不是PPR或移除force-dynamic。开启该标志后,Next.js会尝试对每个路由进行预渲染,包括API路由。当它在我的OpenGraph处理程序中遇到new URL(request.url) 时,会中止并记录诊断信息。错误信息写着“OpenGraph图像生成失败”,但这其实是误导——它只是一次静态生成中止,并非运行时失败。

hideLogsAfterAbort的作用: 它会抑制对那些确实无法静态预渲染的路由的预渲染中止诊断。你的OpenGraph路由在运行时仍然可以正常工作。唯一的影响是构建输出更干净。

关于PPR与缓存组件的说明: 注释掉force-dynamic并不会开启PPR。真正触发此行为的标志是cacheComponents。如果未来通过experimental.ppr配置开启真正的PPR,同样的修复也适用。

// These are NOT the same:
export const dynamic = "force-dynamic"; // explicit opt-out
cacheComponents: true;
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章