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

如何在NextJS应用中加载运行时环境变量?多K8部署最佳替代方案

最佳替代方案

方案1:利用 _app.tsx 的 getInitialProps

虽然Next.js文档不推荐在普通页面使用getInitialProps,但在_app.tsx中使用它是官方允许的方式,能在服务端统一获取环境变量并传递给所有页面。

代码示例:

// _app.tsx
import type { AppProps } from 'next/app'

function MyApp({ Component, pageProps, envVars }: AppProps & { envVars: Record<string, string> }) {
  // 将环境变量传递给页面组件,也可存入React上下文或状态管理库
  return <Component {...pageProps} envVars={envVars} />
}

MyApp.getInitialProps = async (appContext) => {
  // K8s注入的环境变量会挂载在process.env下,按需提取
  const envVars = {
    API_URL: process.env.NEXT_PUBLIC_API_URL,
    APP_ENV: process.env.APP_ENV,
    // 其他需要的环境变量...
  }

  // 调用默认的App初始逻辑,获取页面自带的pageProps
  const appProps = await App.getInitialProps(appContext)

  return { ...appProps, envVars }
}

export default MyApp

所有页面都能通过props.envVars拿到统一的环境变量,无需逐个页面编写getServerSideProps。注意:使用getInitialProps会让所有页面失去静态生成(SSG)能力,适合不需要SSG的场景。

方案2:封装高阶组件(HOC)复用getServerSideProps逻辑

如果需要保留部分页面的SSG能力,可以把获取环境变量的逻辑封装成HOC,页面只需导入包裹即可,避免重复代码。

代码示例:

// withEnvProps.tsx
import type { GetServerSideProps, GetServerSidePropsContext } from 'next'

export const withEnvProps = <P extends Record<string, any>>(
  getServerSideProps?: GetServerSideProps<P>
) => {
  return async (ctx: GetServerSidePropsContext) => {
    // 统一提取环境变量
    const envVars = {
      API_URL: process.env.NEXT_PUBLIC_API_URL,
      APP_ENV: process.env.APP_ENV,
    }

    // 如果页面有自定义的getServerSideProps,先执行并获取其返回的props
    let pageProps = {}
    if (getServerSideProps) {
      const result = await getServerSideProps(ctx)
      if ('props' in result) {
        pageProps = result.props
      }
    }

    // 合并环境变量与页面专属props
    return {
      props: {
        ...pageProps,
        envVars,
      },
    }
  }
}

页面中使用方式:

// pages/home.tsx
import { withEnvProps } from '../components/withEnvProps'

function Home({ envVars, pageData }) {
  return (
    <div>
      <p>当前环境:{envVars.APP_ENV}</p>
      <p>页面数据:{pageData}</p>
    </div>
  )
}

// 页面自定义的服务端逻辑(可选)
export const getServerSideProps = withEnvProps(async (ctx) => {
  // 页面专属的服务端数据获取逻辑
  return {
    props: {
      pageData: '首页专属数据',
    },
  }
})

export default Home

这个方案灵活度高,既统一处理了环境变量,又不影响页面自身的服务端逻辑,还能保留无需getServerSideProps页面的SSG能力。

方案3:使用Next.js配置文件定义环境变量

如果环境变量在K8s容器启动时就已确定,无需服务端动态获取,可以在next.config.js中配置,让所有页面直接访问:

// next.config.js
module.exports = {
  // 传统env配置,客户端可直接访问
  env: {
    APP_ENV: process.env.APP_ENV,
    NEXT_PUBLIC_API_URL: process.env.NEXT_PUBLIC_API_URL,
  },
  // Next.js 10+推荐的runtimeConfig,区分服务端/客户端变量
  runtimeConfig: {
    // 仅服务端可访问的私密变量
    SECRET_KEY: process.env.SECRET_KEY,
    // 客户端可访问的公开变量
    public: {
      API_URL: process.env.NEXT_PUBLIC_API_URL,
    },
  },
}

在_app.tsx或页面中通过next/config获取:

// _app.tsx
import getConfig from 'next/config'

const { serverRuntimeConfig, publicRuntimeConfig } = getConfig()

function MyApp({ Component, pageProps }) {
  // 可将变量存入React上下文,方便全局组件访问
  return <Component {...pageProps} apiUrl={publicRuntimeConfig.API_URL} />
}

这个方案无需编写getServerSideProps或getInitialProps,但要注意:runtimeConfig中的非public变量仅能在服务端访问,客户端无法获取;客户端需要的变量必须加NEXT_PUBLIC_前缀或放在public对象中。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 23:52:31