[RFC] .env environment support #11106
Replies: 35 comments 50 replies
-
By default Now excludes .env files from deployments, would there be a plan to change that when/if this RFC lands? |
Beta Was this translation helpful? Give feedback.
-
That sounds quite targeted at pages. That's kind of similar to an issue I have with React or Redux more broadly, when a I lack clearer example but you get the point, you may want to clarify patterns about how to access those variables outside pages. |
Beta Was this translation helpful? Give feedback.
-
Those patterns are already covered by the |
Beta Was this translation helpful? Give feedback.
-
You meant that this an additional feature, but the |
Beta Was this translation helpful? Give feedback.
-
We'll just add extra docs on the way that it should be used. Even currently it's for exposing env variables everywhere including client-side. Recommendation has always been to not expose eg, database passwords, in the Next.js app itself except for reading it in API routes through normal |
Beta Was this translation helpful? Give feedback.
-
Sounds good to me if patterns are well documented. Isolating client side variables in
Normal Not directly related but I've noticed that the To sum it up, I would expect a chain like this:
The |
Beta Was this translation helpful? Give feedback.
-
Use cases for |
Beta Was this translation helpful? Give feedback.
-
Just going to post a piece from our internal docs – not yet sure how relevant it is to this RFC and also, we have room for improvement, but anyway: |
Beta Was this translation helpful? Give feedback.
-
Last comment for me: TS typings are wrong for
@borekb Totally related to #11131 I think in the meantime I'll fallback to runtime config, as my app is not really static. |
Beta Was this translation helpful? Give feedback.
-
To sum it up: I would expect the Using Instead of using CRA prefixing for env variable that should also be available client-side, (honestly I hate it, it's not intuitive) we could just expect the user to call Basically a Meteor-like pattern but that works at build time and with an even less confusing syntax (clearer separation of client-side and server-side settings). |
Beta Was this translation helpful? Give feedback.
-
The types are not wrong though, you shouldn't nest objects in |
Beta Was this translation helpful? Give feedback.
-
I use It also enforces The use of a Do you plan to support such a feature, or at least allow opting in to it?, |
Beta Was this translation helpful? Give feedback.
-
I'd chime in with some challenges around this that might be worth thinking about for you to ignore if you feel they are not helpful. :-)
I run into this pain point a fair bit, including on old projects I haven't looked at in a while and have refactored without updating all the documentation. It would be great to design a mechanism that could display this using reflection (for example at start up, maybe with displaying default values where possible, like
I feel like this is a fairly common pitfall. Having a mechanism whereby it's easy to categorically say "this env var is not safe to export to the client" (or better yet, explicitly having to say "this is safe to export to the client") and have that enforced when bundling, even if someone then tries to access it client side flow, would be valuable. I get that the new data fetching methods help avoid this, but also appreciate there is a lot to take in for new developers and the nature of Next.js (making it easier to do more complex things) means people can run into complexity sooner and get overwhelmed by everything they are trying to take on board at once and so miss things like this. If not feasible, perhaps using reflection to at least warn people what env vars are being exported to the client at dev run time / build time is possible? Update: Just seen the post above by @jesstelford (which I think was added while I was typing) RE: |
Beta Was this translation helpful? Give feedback.
-
This seems like it could be very helpful for cleaning up build processes as well as providing more granular control of what gets sent down to the client. Presently, we have to build a Docker image for each environment we deploy to in order to ensure env vars are included at build time. It seems to me that the feature described here would enable one to build a single Docker image for all environments and then consume the appropriate env vars at runtime. With that said, can we provide a way to have more granular control over which |
Beta Was this translation helpful? Give feedback.
-
@dwest-teo wrote:
While I get this us easy to put under a nice-to-have, it would be really nice and would second this. In practice, I've found being able to easily load configs for different environments super handy. |
Beta Was this translation helpful? Give feedback.
-
I may have missed it, but it feels like we might want access to these env values when setting up App wide components (providers like Apollo)? I'm still getting to know the newer APIs, but looking at https://nextjs.org/docs/advanced-features/custom-app I see |
Beta Was this translation helpful? Give feedback.
-
Added a section on global environment variables through the |
Beta Was this translation helpful? Give feedback.
-
While this proposal is innovative and a step forward for security, I think it's a major step backward for DX. Imo, it's a departure from the simplicity of the rest of the framework. As a developer, I fully expect environment variables to be available globally. Every other framework that I'm aware of uses global environment variables. Changing this will almost certainly cause extra confusion and extra boilerplate code. 1. Client-side environment variables a. Developer should explicitly allow specific variables to be available globally in the static build 2. Server-side environment variables a. All host environment variables should be available globally at runtime Here's an alternate proposal that has a better DX, is easier to reason about, leaves env variables global, and still solves the security issue.# .env
SENTRY_DSN=xxxxx
DB_URL=xxxxx // next.config.js
module.exports = {
// Value picked up from host env at build time
publicEnv: ['SENTRY_DSN']
} // pages/index.js
// This only used from getStaticProps, so it won't be in the client build
const db = () => new DbClient({url: process.env.DB_URL})
export async function getStaticProps() {
const data = await db().fetchData()
return { props: {data} }
}
export default function HomePage() {
return <div>
<h1>Sentry DSN: {process.publicEnv.SENTRY_DSN}</h1>
{/* throws TypeError: Cannot read property 'DB_URL' of undefined */}
<div>{process.env.DB_URL}</div>
</div>
} // pages/api/getItem.js
export default async function ApiRoute(req, res) {
const data = await new DbClient({url: process.env.DB_URL}).fetchData()
return res.json({ data })
}
Unless I'm missing something, I don't think there are any technical blockers for this approach. |
Beta Was this translation helpful? Give feedback.
-
I might have missed this, but will the |
Beta Was this translation helpful? Give feedback.
-
Regading
Perhaps stubbing process.env = process.env.NODE_ENV === 'development'
? (
new Proxy({}, {
get (target, property) {
throw new Error(`Looks like you're trying to use "process.env.${property}", read article http://xyz on how to pass configuration to the browser`)
}
})
)
: {}; It would make trying to use any edit: 🤔 although technically, people may rely on those values being |
Beta Was this translation helpful? Give feedback.
-
I've updated the RFC based on the feedback and confusion, leaving out the export const config part, we might introduce it at a later point in time. For now keeping it simple:
|
Beta Was this translation helpful? Give feedback.
-
I am not 100% sure I completely understand.
Is this correct ? |
Beta Was this translation helpful? Give feedback.
-
The RFC sounds great regarding env variables, but it is still unclear to me how it interacts with @kxmatejka saying "There is really no need for something like this." is maybe too simplified, as we indeed need a good pattern to load env variables, and the current proposal seems very good. However it shows that env variables are not sufficient in themselves to configure a complex application. This is the most basic configuration of a Vulcan app (Meteor) for instance: {
"public": {
"title": "Your site title",
"tagline":"Your site tagline",
"logoUrl": "http://placekitten.com/250/80",
"logoHeight": "80",
"logoWidth": "250",
"faviconUrl": "/favicon.ico",
"language": "en",
"locale": "en",
"twitterAccount": "foo",
"facebookPage": "http://facebook.com/foo",
"googleAnalytics": {
"apiKey": "foo123"
},
"backoffice": {
"enabled": true
},
"apolloSsr": {
"disable": false
}
},
"defaultEmail": "hello@world.com",
"mailUrl": "smtp://username%40yourdomain.mailgun.org:yourpassword123@smtp.mailgun.org:587/",
"oAuth": {
"twitter": {
"consumerKey": "foo",
"secret": "bar"
},
"facebook": {
"appId": "foo",
"secret": "bar"
}
},
} and this is only a simple setting, a real life app has twice as many settings. In the current proposal, how do you expect such configs to be handled? Using runtime configs or transferring everything to a |
Beta Was this translation helpful? Give feedback.
-
Something that do not seem to be specified : the .env file loading mechanism might need to be exposed to developer to handle the special case of custom server. You would expect it to access the same env variable as pages for example but it uses a custom build (or no build), so devs have to mimic Next.js feature somehow. |
Beta Was this translation helpful? Give feedback.
-
Hello fellas, first of all thanks for your great work and continuous development and detailed work on the issues and RFCs. I would like to give my support to this feature and RFC because a standardized way of dealing with environment variables is needed (both for client and server sides), without having to add extra packages like dotenv. A couple of comments. Thanks! |
Beta Was this translation helpful? Give feedback.
-
This is looking great. Excited for the RFC to land on stable. Would it be accurate to say that the new approach to In other words, the variables in But when you deploy it to now.sh, To really hammer this point home, if you put a |
Beta Was this translation helpful? Give feedback.
-
It's a bit unclear to me how I can control these environments. What does the following mean:
How do I override this as needed, for example setting the environment to |
Beta Was this translation helpful? Give feedback.
-
This feature was released in Next.js 9.4! |
Beta Was this translation helpful? Give feedback.
-
Hi, I am trying to setup Jest to work as closely as Next as possible. What would be the shortest path in your opinion to have the same behaviour regarding Edit: ok reading previous message I've already asked smth similar ^^ the questions comes back to my mind every time I need to setup a new 3rd party tool, eg Storybook, Jest, Cypress etc. I strive to have a really unified build time behaviour, based on Next's one |
Beta Was this translation helpful? Give feedback.
-
Can we add path to env folder in config? It's common to have private data in private folder, not in root. |
Beta Was this translation helpful? Give feedback.
-
Goals
.env
) support with the same.env
file loading semantics as Create React App: https://create-react-app.dev/docs/adding-custom-environment-variables/#what-other-env-files-can-be-usedBackground
Over the last few months we've had a lot of feedback from companies running into confusion around how to handle environment variables.
The main feedback has been mostly:
dotenv
(almost 50% of Next.js apps).Proposal
Node.js-only environment variables
Currently you can already access
process.env
in the Node.js environment only. Meaning that environment variables are private by default. Next.js never inlines environment variables unless you specify to do so under theenv
key.An example of this is:
This would also cover the Server → Browser handoff, as an environment variable could be returned in the data fetching methods to expose it:
.env loading
Environment variables will be loaded from
.env
files, using the same loading mechanism as Create React App: https://create-react-app.dev/docs/adding-custom-environment-variablesFor example:
Will set
ACCESS_TOKEN
toabcdefgh
Global public environment variables
Sometimes you need to configure something globally. A good example of this is the Sentry DSN key. To allow for this you can prefix global environment variables with
NEXT_PUBLIC_
in order to make it globally available in both node.js and the browser. Note that this will expose the variable to the browser when used, so it can't be used for secrets.Overall these changes should simplify usage of environment variables for the majority of use cases.
Beta Was this translation helpful? Give feedback.
All reactions