Some days ago I had to initialise a new Angular app for a side project of mine. The use case would be fairly simple, and I needed some basic features like user authentication and some entities to store on a backend.
In such cases Supabase is a great open-source alternative to setting up a custom backend, and integrating it into an Angular app is fairly simple, given the existing supabase dependencies like @supabase/supabase-js. The only prerequisite to make it work is initialising a supabase project and generating an API key.
However, I found out that managing environment variables in an Angular project is not really straight forward. Once we generate a project via the Angular CLI, we get the environment.ts
and environment.prod.ts
files, but these cannot be used for declaring such API keys, especially if we want to push our codebase to a github repository.
After some research I did, I discovered @ngx-env/builder which, as it seems, provides us with a clean and secure way to store our environment variables.
You can find a sample project showcasing how it works here:
dimeloper / angular-environment-variables
A sample Angular app that showcases how to set up env variables for different environments.
Angular Environment Variables
A sample Angular app that showcases how @ngx-env/builder
can be used to introduce Environment Variables and different app environments within an Angular application.
Add package and adjust angular configuration
- open a terminal
- go to the project root folder
- execute
ng add @ngx-env/builder
Define Environment variables
- create
.env
file in your local project directory - add it in your
.gitignore
- extend the
Env
interface withinenv.d.ts
so that the new variables and their types are added belowNODE_ENV
(e.g.readonly NG_APP_ENV: string;
) - add your environment variables and their values within your local
.env
file with the following format:
NG_APP_PUBLIC_SUPABASE_URL=https://test.supabase.co
NG_APP_PUBLIC_SUPABASE_ANON_KEY=keykeykeyvaluevalue
Note that all the environment variables should be prefixed with NG_
.
Differentiate environments across serve and build tasks
You could possible use the default NODE_ENV
values to differentiate between e.g. development
and production
environments, however I prefer having my own app environment valuesβ¦
Getting started
Once we are at our Angular project root directory we can simply run ng add @ngx-env/builder
to get started. This command will install the necessary dependency, adjust the application builders accordingly and generate the environment types within env.d.ts
.
Once this is complete we can extend the generated env.d.ts
and its Env interface with our expected environment variables. For example:
declare interface Env {
readonly NODE_ENV: string;
// Replace the following with your own environment variables.
readonly NG_APP_ENV: string;
readonly NG_APP_PUBLIC_SUPABASE_URL: string;
readonly NG_APP_PUBLIC_SUPABASE_ANON_KEY: string;
}
Please keep in mind that the NG_APP_
prefix is mandatory. In case you need to change it please consult the related documentation.
Defining Environment Variables
Now we can use .env
files on our local and production environments with the corresponding values. First we need to make sure that our .gitignore
includes the .env
file. Then we can create our local .env
file as such:
NG_APP_PUBLIC_SUPABASE_URL=https://test.supabase.co
NG_APP_PUBLIC_SUPABASE_ANON_KEY=keykeykeyvaluevalue
Since we included this file as part of our .gitignore
, these values won't be pushed to our github repository.
Usage in components / templates
We can import the actual values of our environment variables in our components as such:
supabaseUrl = import.meta.env.NG_APP_PUBLIC_SUPABASE_URL;
Basically the import.meta.env
object will include all the environment variables we've defined.
Differentiate environments across serve and build tasks
We could possibly use the default NODE_ENV
values to differentiate between e.g. development
and production
environments, however I prefer having my own app environment values which for this sample project, I've defined within package.json
.
Example:
"scripts": {
"start:dev": "NG_APP_ENV=dev ng serve",
"start:staging": "NG_APP_ENV=staging ng serve",
"start:production": "NG_APP_ENV=production ng serve",
"build": "NG_APP_ENV=production ng build"
}
By doing this we have a clear app environment separation, while we are also able to differentiate pieces of implementation depending on the app environment, e.g. if we want to show a teaser component only on production or staging.
Deployment / usage in production
Once our local setup is complete, we can overwrite the values of our environment variables, just by defining them on the staging/production system environment (e.g. export NG_APP_PUBLIC_SUPABASE_URL="environment.specific.url"
), or by creating an .env
file in there, including all the enviroment specific values (e.g. staging values on the testsystem, production values on the live server).
Conclusion
Managing API keys and secret values that should be handled as environment variables is an essential part of any frontend application that should be production ready. The @ngx-env/builder package provides us with an elegant and straightforward way to do so, when it comes to Angular apps. Enjoy!
Top comments (4)
Thanks for your help! I was wondering if you still managed to get your browser to auto refresh after using the
@ngx-env/builder:application
builder in your angular.json file. It seems I need to re-runng serve ...
each time I make edits to my typescript code.Hey there, you're welcome. The live reload mechanism works fine in the projects I've used the env builders, whenever I edit a typescript file. Can you doublecheck that in the
"serve"
configuration within yourangular.json
the@ngx-env/builder:dev-server
is declared as builder?No worries. I ended up solving the issue. I used βng updateβ to update angular from version 17 to version 18. The ngx-env/builder was on version 18
Nice, glad to hear you manage to sort it out!