环境变量不起作用(Next.JS 9.4.4)

Per*_*ixo 5 javascript environment-variables reactjs contentful next.js

所以我使用 Contentful API 从我的帐户中获取一些内容并将其显示在我的 Next.Js 应用程序中(我使用的是 next 9.4.4)。这里非常基本。现在为了保护我的凭据,我想使用环境变量(我以前从未使用过它,而且我对所有这些都不熟悉,所以我有点迷茫)。

我正在使用以下内容在我的 index.js 文件中创建 Contentful Client:

const client = require('contentful').createClient({
    space: 'MYSPACEID',
    accessToken: 'MYACCESSTOKEN',
});
Run Code Online (Sandbox Code Playgroud)

MYSPACEID并且MYACCESSTOKEN是硬编码的,所以我想将它们放在一个 .env 文件中以保护它,并且在部署在 Vercel 上时不要将其公开。

我创建了一个.env文件并像这样填充它:

CONTENTFUL_SPACE_ID=MYSPACEID
CONTENTFUL_ACCESS_TOKEN=MYACCESSTOKEN
Run Code Online (Sandbox Code Playgroud)

当然,MYACCESSTOKENMYSPACEID包含正确的键。

然后在我的 index.js 文件中,我执行以下操作:

const client = require('contentful').createClient({
  space: `${process.env.CONTENTFUL_SPACE_ID}`,
  accessToken: `${process.env.CONTENTFUL_ACCESS_TOKEN}`,
});
Run Code Online (Sandbox Code Playgroud)

但是当我使用它时它不起作用yarn dev,我收到以下控制台错误:

{
  sys: { type: 'Error', id: 'NotFound' },
  message: 'The resource could not be found.',
  requestId: 'c7340a45-a1ef-4171-93de-c606672b65c3'
}
Run Code Online (Sandbox Code Playgroud)

这是我的主页以及我如何从 Contentful 检索内容并将它们作为道具传递给我的组件:

const client = require('contentful').createClient({
    space: 'MYSPACEID',
    accessToken: 'MYACCESSTOKEN',
});

function Home(props) {
  return (
    <div>
      <Head>
        <title>My Page</title>
        <link rel="icon" href="/favicon.ico" />
      </Head>

      <main id="page-home">
        <Modal />
        <NavTwo />
        <Hero item={props.myEntries[0]} />
        <Footer />
      </main>
    </div>
  );
}

Home.getInitialProps = async () => {
  const myEntries = await client.getEntries({
    content_type: 'mycontenttype',
  });

  return {
    myEntries: myEntries.items
  };
};

export default Home;
Run Code Online (Sandbox Code Playgroud)

你认为我的错误来自哪里?

在研究我的问题时,我还尝试了解apinext.js 中的工作原理,因为我读过在其中创建 api 请求可能会更好,pages/api/但我不明白如何获取内容,然后将响应传递到我的页面组件就像我在这里做的一样..

任何帮助将非常感激!

编辑 :

所以我通过将我的 env 变量添加到我的next.config.js像这样来解决这个问题:

const withSass = require('@zeit/next-sass');

module.exports = withSass({
  webpack(config, options) {
    const rules = [
      {
        test: /\.scss$/,
        use: [{ loader: 'sass-loader' }],
      },
    ];

    return {
      ...config,
      module: { ...config.module, rules: [...config.module.rules, ...rules] },
    };
  },
  env: {
    CONTENTFUL_SPACE_ID: process.env.CONTENTFUL_SPACE_ID,
    CONTENTFUL_ACCESS_TOKEN: process.env.CONTENTFUL_ACCESS_TOKEN,
  },
});

Run Code Online (Sandbox Code Playgroud)

小智 88

如果您使用的是最新版本的nextJs(9以上)

然后按照以下步骤操作:

  1. 在项目的根目录中创建一个.env.local文件。
  1. 将前缀NEXT_PUBLIC_添加到所有环境变量中。
eg: NEXT_PUBLIC_SOMETHING=12345
Run Code Online (Sandbox Code Playgroud)
  1. 在任何 JS 文件中使用它们,例如带有前缀process.env
eg: process.env.NEXT_PUBLIC_SOMETHING
Run Code Online (Sandbox Code Playgroud)

  • 这就是我需要做的 - NEXT_PUBLIC_ 是我将变量公开给浏览器所缺少的。 (8认同)
  • 这会将您的密钥暴露给公众,以便任何人都可以访问它。不要这样做。请参阅其他 `/pages/api` 答案 (2认同)

dal*_*nmh 18

我建议在 nextjs 9.4 及更高版本上更新,使用以下示例:

.env.local
NEXT_PUBLIC_SECRET_KEY=i7z7GeS38r10orTRr1i
Run Code Online (Sandbox Code Playgroud)

在代码的任何部分,您都可以使用:

.js
const SECRET_KEY = process.env.NEXT_PUBLIC_SECRET_KEY
Run Code Online (Sandbox Code Playgroud)

请注意,它必须与密钥“ NEXT_PUBLIC_SECRET_KEY ”同名,而不仅仅是“SECRET_KEY”

当你运行它时,请确保日志中显示

$ next dev
Loaded env from E:\awesome-project\client\.env.local
ready - started server on http://localhost:3000
...
Run Code Online (Sandbox Code Playgroud)

要了解有关环境变量的更多信息,请参阅此链接

  • 请注意,这种方法**不能保护**您的秘密 - 它们对前端包中的任何人都是可见的。为了保护你的秘密,你“必须”创建一个后端函数,正如 Nikolai Kiselev 在他的回复中所建议的那样。.env 文件可用于存储机密,但*永远不要*在它们前面加上“NEXT_PUBLIC_”前缀,因为这使得它们对前端也可见。如果没有“NEXT_PUBLIC_”前缀,该变量将仅在 next.js 后端中可用,这正是您想要的。 (5认同)
  • 使用 NEXT_PUBLIC 是否需要这样做 (2认同)

Nik*_*lev 12

您不能在不公开 API 凭据的情况下从客户端发出此类请求。你必须有一个后端。

您可以使用 Next.js/pages/api向Contentful发出请求,然后将其传递给您的前端。

只需创建一个.env文件,添加变量并在您的 API 路由中引用它,如下所示:

process.env.CONTENTFUL_SPACE_ID
Run Code Online (Sandbox Code Playgroud)

从 Next.js 9.4 开始,你不需要 next.config.js 了。


通过将变量添加到next.config.js 您已经向客户端公开了秘密。任何人都可以看到这些秘密。

新环境变量支持

使用 Contentful 创建 Next.js 应用程序并使用 Vercel 进行部署

使用 Next.js 和 Contentful 的博客示例


小智 8

您必须在 next.config.js 中进行简单的更改

const nextConfig = {
  reactStrictMode: true,
  env:{
    MYACCESSTOKEN : process.env.MYACCESSTOKEN,
    MYSPACEID: process.env.MYSPACEID,
  }
}

module.exports = nextConfig
Run Code Online (Sandbox Code Playgroud)

像这样改变它


OZZ*_*ZIE 7

不要放入敏感的东西,next.config.js 但是就我而言,我有一些根本不敏感的环境变量,我需要它们在服务器端和客户端,然后你可以这样做:

// .env file:
VARIABLE_X=XYZ

// next.config.js
module.exports = {
  env: {
    VARIABLE_X: process.env.VARIABLE_X,
  },
}
Run Code Online (Sandbox Code Playgroud)


Ach*_*ain 0

参考文档

您需要在项目中添加 next.config.js 文件。在该文件中定义环境变量,这些变量将在您的应用程序中可用。

  • @Perdixo,这是不正确的答案,因为建议的方式**公开**凭据。它只能用于可以公开发布的变量。 (3认同)