根据环境添加自定义 headers 到 Next.js 响应

Add custom headers to Next.js responses based on environment

我正在尝试将 X-Robots-Tag header 添加到所有 Next.js HTTP 响应,基于服务器部署到的环境中的 某些东西 --这是一个环境变量(我的偏好)还是其他任何东西。

我的 Next.js 应用程序部署到两个环境:使用生产 Next.js 构建 (NODE_ENV="production") 但连接到 non-prod 服务的集成测试环境,以及服务于用户流量的实际生产环境。我只想将 header 添加到集成测试环境。

我已经尝试根据 process.env.INTEGRATIONTESTENVheaders() in next.config.js 中有条件地添加 header ,但是像 process.env.XYZ 这样的任何环境变量似乎都是在构建时评估的,而不是在运行时。例如,这不起作用,即使 INTEGRATION_TEST_ENV 环境变量在服务器上设置为字符串“true”:

headers() {
      if (process.env.INTEGRATION_TEST_ENV === "true") {
        console.log("This code will never be run. The condition never evaluates to true, despite the runtime env var actually being set to 'true'.")
        return [
          {
            source: "/:path*",
            headers: [
              {
                key: "X-Robots-Tag",
                value: "none",
              },
            ],
          },
        ]
      }
    },

我也不能使用 next.config.js 的阶段,因为我的集成测试和“实际生产”都是 运行 生产构建和生产服务器。

一个 custom server 可能会解决问题,但似乎有点矫枉过正,尤其是在失去自动静态优化的情况下。

有什么方法可以根据运行时环境变量添加header吗?

getServerSideProps(context)选项是使用_middleware page:

// pages/_middleware.js
import { NextResponse } from "next/server";

export function middleware() {
  const res = NextResponse.next();

  // `process.env` evaluated at build time
  if (process.env.INTEGRATION_TEST_ENV === "true") {
    res.headers.set("X-Robots-Tag", "none");
  }

  return res;
}

我不确定您是否只编译一次然后每个部署目标都会获得相同的包(因此环境变量将是“baked-in”),但是如果您能找到解决方法那,这可能会起作用。

另一种方法

export default function Home() {
  return "Hello, world!";
}

// automatic static optimization no longer applies 
export function getServerSideProps(context) {
  if (process.env.INTEGRATION_TEST_ENV === "true") {
    context.res.setHeader("X-Robots-Tag", "none");
  }

  return {
    props: {},
  };
}