This project was generated with Angular CLI version 12.2.14.
This is a PoC to load dynamic brand styles for browser and server-side generation during build time using environment variables.
- Dynamically Load CSS with the Angular CLI by Juri Strumpflohner
- Environment-Based Index HTML with Angular CLI by Netanel Basal - thanks Jay for the reference
- How to pass environment variables at building time in an Angular application using .env files by Riccardo Andreatta
- Add the following
link
to theindex.html
file, to hold dynamically injected brand style file
<link id="brand-style" rel="stylesheet">
- Add a directory for all the brand specific style files, in this example it's
src/brand-styles
- Add separate style files in this directory for each brand like this
- src
- brand-styles
- one.scss
- two.scss
- Update
angular.json
->projects/[project-name]/architect/build/options/styles
with the following content
{
"input": "src/brand-styles/one.scss",
"bundleName": "one.min",
"inject": false
},
{
"input": "src/brand-styles/two.scss",
"bundleName": "two.min",
"inject": false
}
- This will tell the Angular CLI to compile these styles into their own separate bundles, but do not inject them in the
index.html
file during build - To set the brand in the
process.env
, we are usingcross-env
by Kent C. Dodds in thepackage.json
file - To inject the style in
index.html
during build, we are using@angular-builders/custom-webpack
by JeB which gives us an optionindexTransform
that takes a.ts
or.js
file and uses it to transformindex.html
during the build - We have a file called
index-html-transform.ts
on the root of the project that get the brand value fromprocess.env.BRAND
and updates thehref
of the placeholderlink
element that we have inindex.html
file
This is pretty much everything to get going!
Now, most likely we will need the selected brand in our components/services as well. For that, we have a file called set-environment.ts
on the root of the project, which takes the brand from process.env.BRAND
and updates the src/environments/environment.ts
file with the brand value. And we can simply import brand
from our environment file in our application.
- The first thing is to see if this solution makes sense or we have better ways to handle the situation?
- If this solution makes sense, will it work with SSR as expected?
- The
environment.ts
file gets updated with the build. We need to make sure that other details in the file are not affected except the brand
npm run start:one
: Serves the app with brandone
styling athttp://localhost:4200
npm run build:one
: Builds the app with brandone
styling in thedist
foldernpm run dev:ssr:one
: Serves the app with brandone
styling built using Angular Universal athttp://localhost:4200
npm run build:ssr:one
: Builds the app with brandone
styling built using Angular Universal in thedist
foldernpm run serve:ssr:one
: Serves the app from thedist
folder that was built using the above script athttp://localhost:4000
npm run prerender:one
: Prerenders the app with brandone
styling built using Angular Universal in thedist
folder
npm run start:two
: Serves the app with brandtwo
styling athttp://localhost:4200
npm run build:two
: Builds the app with brandtwo
styling in thedist
foldernpm run dev:ssr:two
: Serves the app with brandtwo
styling built using Angular Universal athttp://localhost:4200
npm run build:ssr:two
: Builds the app with brandtwo
styling built using Angular Universal in thedist
foldernpm run serve:ssr:two
: Serves the app from thedist
folder that was built using the above script athttp://localhost:4000
npm run prerender:two
: Prerenders the app with brandtwo
styling built using Angular Universal in thedist
folder