Understanding Environments and Stages
NRN relies on environment variables to function correctly.
Those variables are provided differently depending on the environment.
Table of contents
- Development environment vs Vercel environment
- Public environment variables vs private env variables
- What is an environment?
- What is a stage?
Development environment vs Vercel environment
When working on the development environment (localhost), the variables from .env.local and then .env are used by the webpack configuration. The variable defined in .env.local take precedence over those in .env, when they clash.
When deploying an instance to the Vercel’s platform, the variables used are the one that belong to the configuration file related to that instance, such as:
- When running
yarn deploy:customer1: This script will deploy an instance using thevercel.customer1.staging.jsonfile. - When running
yarn deploy:customer1:production: This script will deploy an instance using thevercel.customer1.production.jsonfile.
When pushing changes to the remote repository, it triggers a GitHub action. The action runs the yarn deploy:* script, and it works exactly the same as if you were running it from your local computer, except it’s done on a CI server.
In those files, it’s the
build.envpart that is used at build time (build is done on Vercel), which basically replaces all references of every environment variable by the actual value (“string replace”, at build time).
Public environment variables vs private env variables
It can be very quick and easy to share some sensitive environment variable to the browser, usually by mistake.
In order to make it obvious what variables are meant to be shared with the browser (and thus, to be public), Next.js prefixes them with NEXT_PUBLIC_.
As a good practice, we strongly recommend to only have public variables in your .env file. All non-public variables should be defined in .env.local instead.
With this setup, it becomes clearer what’s intended to be shared with the browser and what’s actually private. And, what should be private shouldn’t be tracked by Git either, and thus only defined in the local config file.
An exception to this rule is when an environment variable isn’t public, but isn’t sensitive either, and therefore conveniently stored in
.envbecause it’s just easier for collaboration.
What is an environment?
An environment is “where” the application is running. It can be either “development” (localhost) or “production” (on Vercel’s servers).
The
environmentis defined by theNODE_ENVenvironment variable.Tip: It is not possible to use any other value than
developmentandproduction, as enforced by Next
When working on your local computer, you automatically use NODE_ENV=developement.
The environment affects how the application is bundled, it is defined at build time. (webpack, hot-reloading, etc.)
e.g: When building the app using the
developmentenvironment, you have access to PropTypes warnings, but you won’t when usingproduction.
What is a stage?
A stage is “how” the application is running. It can be either “development” (localhost), “staging” or “production” (on Vercel’s servers)
You can even add more stages, if you need
The
stageis defined by theNEXT_PUBLIC_APP_STAGEenvironment variable.Tip: You can use any stage name you like, just make sure to use a slug (no space, no special chars, no accents, etc.).
- When working on your local computer, NRN automatically uses
NEXT_PUBLIC_APP_STAGE=developement(as defined in.env). - When creating a Vercel preview deployment (e.g: when pushing a commit/branch (CD), or when using
yarn deploy, etc.), NRN automatically usesNEXT_PUBLIC_APP_STAGE=staging(as defined invercel.customer1.staging.json). - When creating a Vercel production deployment (e.g: when using
yarn deploy:customer1:production, or when merging a PR to themasterormainbranch, etc.), NRN automatically usesNEXT_PUBLIC_APP_STAGE=production(as defined invercel.customer1.production.json).
The stage changes the behaviour of the application, because we sometimes need the application to behave differently depending on the stage.
The stage is automatically selected based on the
yarn deploy:*script used. (any push onmasterormainis considered as production stage, while any push on any other branch is considered as staging stage)
e.g: In
productionstage, the Locize configuration uses theproductionversion. When using another stage, it uses thelatestversion.
e.g: We don’t want to enable the same level of debugging in production environment. For instance, Locize is configured to be in
debugmode only in non-production stages.