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

如何在Next.js中禁用Route Handler的路由预渲染?

Next.js 禁用Route Handler预渲染及Sitemap问题解决

问题背景

我使用Route Handler创建了app/blog/rss.xml/route.ts路由文件,代码如下:

import { getBlogPosts } from '@/routines/getBlogPosts.ts';
import Rss from 'rss';

const SITE_URL = 'https://ray.run';

export const GET = async () => {
  const blogPosts = await getBlogPosts();

  const feed = new Rss({
    description: 'Lessons learned scaling Playwright test automation',
    feed_url: `${SITE_URL}/blog/rss.xml`,
    language: 'en',
    site_url: SITE_URL,
    title: 'Rayrun Blog',
  });

  for (const blogPost of blogPosts) {
    if (!blogPost.publishedAt) {
      continue;
    }

    feed.item({
      author: blogPost.author.name,
      date: blogPost.publishedAt,
      description: blogPost.description,
      guid: `${SITE_URL}/blog/${blogPost.guid}`,
      title: blogPost.title,
      url: `${SITE_URL}/blog/${blogPost.slug}`,
    });
  }

  return new Response(feed.xml(), {
    headers: {
      'content-type': 'application/xml',
    },
  });
};

执行next build时,Next.js会尝试预渲染该路由,由于构建环境无法访问数据库,GET请求执行失败导致构建报错。尝试添加export const dynamic = "force-dynamic";无效,目前临时通过环境变量判断返回占位内容,但希望找到更合理的解决方案。同时sitemap.ts也存在相同问题,添加dynamic属性完全被忽略。

解决方案

1. Route Handler 禁用预渲染

在route.ts文件中同时添加dynamic和revalidate配置,确保Next.js在构建阶段不预渲染该路由,改为每次请求动态生成内容:

import { getBlogPosts } from '@/routines/getBlogPosts.ts';
import Rss from 'rss';

const SITE_URL = 'https://ray.run';

// 强制动态路由,禁用预渲染
export const dynamic = "force-dynamic";
// 禁止缓存,确保每次请求重新获取数据
export const revalidate = 0;

export const GET = async () => {
  const blogPosts = await getBlogPosts();

  const feed = new Rss({
    description: 'Lessons learned scaling Playwright test automation',
    feed_url: `${SITE_URL}/blog/rss.xml`,
    language: 'en',
    site_url: SITE_URL,
    title: 'Rayrun Blog',
  });

  for (const blogPost of blogPosts) {
    if (!blogPost.publishedAt) {
      continue;
    }

    feed.item({
      author: blogPost.author.name,
      date: blogPost.publishedAt,
      description: blogPost.description,
      guid: `${SITE_URL}/blog/${blogPost.guid}`,
      title: blogPost.title,
      url: `${SITE_URL}/blog/${blogPost.slug}`,
    });
  }

  return new Response(feed.xml(), {
    headers: {
      'content-type': 'application/xml',
    },
  });
};

2. Sitemap 问题处理

由于sitemap.ts会忽略dynamic属性,无法通过配置禁用预渲染,因此需要将sitemap.ts重写为Route Handler形式:创建app/sitemap.xml/route.ts文件,用动态路由生成站点地图,同样添加dynamic和revalidate配置避免构建阶段执行数据查询:

export const dynamic = "force-dynamic";
export const revalidate = 0;

export const GET = async () => {
  // 这里替换为你的站点地图生成逻辑
  const sitemapContent = await generateSitemap();
  
  return new Response(sitemapContent, {
    headers: {
      'content-type': 'application/xml',
    },
  });
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 01:18:10