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

如何在Next.js App Router的客户端模块中使用运行时变量?

在Next.js App Router中为工具模块获取运行时变量的方案

App Router确实移除了publicRuntimeConfig,这源于其架构对服务端/客户端边界的严格隔离。你的困惑并非操作错误,而是架构设计带来的必然限制,以下是几种实用解决方案:

1. 依赖注入(推荐)

将运行时变量作为参数传入工具函数,而非让工具函数主动获取,这种方式最贴合模块化设计,同时兼容服务端和客户端:

// utils/your-tool.js
export function processRuntimeData(data, runtimeVars) {
  // 使用传入的runtimeVars处理数据
  return data.map(item => ({ ...item, env: runtimeVars.NEXT_PUBLIC_APP_ENV }));
}

// 服务端组件中调用
import { processRuntimeData } from '@/utils/your-tool';
import { env } from 'process';

export default async function ServerComponent() {
  const data = await fetchSomeData();
  const processedData = processRuntimeData(data, {
    NEXT_PUBLIC_APP_ENV: env.NEXT_PUBLIC_APP_ENV
  });
  return <ClientComponent processedData={processedData} />;
}

// 客户端组件中调用(若需客户端侧处理)
'use client';
import { processRuntimeData } from '@/utils/your-tool';

export default function ClientComponent({ processedData }) {
  const clientProcessed = processRuntimeData(processedData, {
    NEXT_PUBLIC_APP_ENV: process.env.NEXT_PUBLIC_APP_ENV
  });
  return <div>{clientProcessed.map(item => <p key={item.id}>{item.env}</p>)}</div>;
}

2. 创建运行时变量初始化模块

若工具函数需频繁复用相同变量,可创建专门的初始化模块,在服务端和客户端分别完成初始化:

// lib/runtime-vars.js
let runtimeVars = null;

export function initRuntimeVars(vars) {
  runtimeVars = vars;
}

export function getRuntimeVars() {
  if (!runtimeVars) {
    throw new Error('Runtime vars未初始化,请先调用initRuntimeVars');
  }
  return runtimeVars;
}

// 服务端入口(如root layout)
import { initRuntimeVars } from '@/lib/runtime-vars';
import { env } from 'process';

export default async function RootLayout({ children }) {
  initRuntimeVars({
    NEXT_PUBLIC_APP_ENV: env.NEXT_PUBLIC_APP_ENV,
    API_URL: env.API_URL
  });
  return (
    <html>
      <body>{children}</body>
    </html>
  );
}

// 客户端入口(如单独的client初始化文件)
'use client';
import { initRuntimeVars } from '@/lib/runtime-vars';

initRuntimeVars({
  NEXT_PUBLIC_APP_ENV: process.env.NEXT_PUBLIC_APP_ENV
});

// 工具函数中使用
import { getRuntimeVars } from '@/lib/runtime-vars';

export function processData(data) {
  const vars = getRuntimeVars();
  return data.map(item => ({ ...item, apiUrl: vars.API_URL }));
}

注意:客户端仅能访问带NEXT_PUBLIC_前缀的环境变量,服务端则可访问所有环境变量。

3. 路由处理器统一提供变量(适合纯客户端工具)

若工具函数仅在客户端使用,可通过路由处理器暴露运行时变量,再在客户端工具模块中请求获取:

// app/api/runtime-vars/route.js
import { NextResponse } from 'next/server';
import { env } from 'process';

export async function GET() {
  return NextResponse.json({
    NEXT_PUBLIC_APP_ENV: env.NEXT_PUBLIC_APP_ENV,
    API_URL: env.API_URL // 服务端可安全返回非public变量
  });
}

// utils/client-tool.js
let cachedVars = null;

export async function getRuntimeVars() {
  if (cachedVars) return cachedVars;
  const res = await fetch('/api/runtime-vars');
  cachedVars = await res.json();
  return cachedVars;
}

export async function processClientData(data) {
  const vars = await getRuntimeVars();
  return data.map(item => ({ ...item, apiUrl: vars.API_URL }));
}

该方案适合客户端需动态获取服务端环境变量的场景,建议缓存请求结果以减少网络开销。

为什么组件可行但工具模块不行?

组件属于React渲染流程的一部分,可直接接触服务端上下文或客户端请求能力;而普通工具模块独立于渲染流程,没有内置的上下文或请求通道,因此无法直接获取运行时变量,必须通过显式传递或初始化的方式拿到变量。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 00:45:03