How can I pass an environment variable to NPM build script?

I’m building an Eleventy site on Cloudflare Pages, and looking for ways to create a nonce for Content-Security Policy. The tricky part is having to have a string that is replaced server-side (Worker in this case) that must remain secret.

I’ve created a config variable in Eleventy that I can pass on the command line by typing

$ VAR=process.env.REPLACEMENT npm run build

Where “REPLACEMENT” is the string value I want to keep secret. This works great on local development, but I cannot access my Pages environment variable when I deploy to Preview | Prod. I think I should be able to pass something like

$ VAR=context.env.REPLACEMENT npm run build

in the Pages Build settings, but it just renders the string “context.env.REPLACEMENT” instead of the replaced value.

This is a hard requirement for nonces, that the replacement value be kept secret, otherwise I’d just hard-code it and let the Worker find and replace that string. I might just be calling the environment variable incorrectly, or maybe what I’m wanting to do is not possible.

You can set environment variables in the Settings of your Pages project. If they are secret, you can encrypt them so they won’t be visible in the dashboard any more after you enter them.

Cool, we’re getting closer.

I’ve set the variable in the Pages > Settings, and made sure it was encrypted. Now I’m looking for a way to get that encrypted value, and plug it into the Pages > Build Config > Build Command so it’s passed through and eventually ends up a string to be replaced by the Worker.

It will be set in the environment when your build command runs. You don’t need to pass it on the command line.

I think I’m doing a not-great job asking the right question.

In my Eleventy Nunjucks template, I have a placeholder {{ config.nonceReplacement }} that will become the secret string the Worker will replace. That value is derived from process.env.NONCE_SECRET. I can pass this around easily in Eleventy, but am having trouble passing NONCE_SECRET=context.env.PAGES_SECRET into the build command.

Eleventy has gotten high on the list of “stuff I need to try” but I haven’t yet, so there’s that.

But it seems odd to me to be passing what looks like literal Javascript in an environment variable on the command line. The running code should have the environment variable in process.env at build time. You should be able to just get process.env.NONCE_SECRET in the code, assuming NONCE_SECRET is the name of the variable you set in the project.

1 Like

I’ve been thinking about our conversation for a couple hours. In doing so, I realized I’ve got a few wrong assumptions:

  1. I’m working locally without an .env file, so having to pass variables on the command line
  2. I have named the CF environment variable differently than the local process.env.VAR

These things together suggest I can follow this thread and it should work as expected. I also found this article Hassle-Free Build and Deployment Using Cloudflare Pages that’s doing roughly the same thing with React. I’ve got decent faith this’ll solve the problem.

I appreciate the help and discussion @i40west

1 Like

This topic was automatically closed 3 days after the last reply. New replies are no longer allowed.