feat: Runtime app settings for frontend service #243
Closed
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
What kind of change does this PR introduce?
Feature
Why was this change needed?
The Problem
Due to nextjs "freezing" process.env variables in client code at build time, these cannot be changed or configured properly. This is backed up by the quote in the nextjs docs; https://nextjs.org/docs/pages/building-your-application/configuring/environment-variables#bundling-environment-variables-for-the-browser
This has been working so far, because most people are building Postiz, by running it with
npm run dev
- which "compiles" the .env file into the frontend code - I assume you're doing something very similar on Railway.We can actually prove this is the case, if we have the following entry in our .env file;
FRONTEND_URL="I_LIKE_WAFFLES"
Then build (which is what the docker build is doing) and grep
dist/apps/frontend
:This means that after a
npm run build
, the.env
file is effectively ignored in the client code, making configuration somewhat impossible!process.env
in the backend code is unaffected by this kind of freezing, as that is run server-side.The Solution
We need to be able to read these variables at runtime, in the client. We cannot build them into the code at build-time, because that is what is happening at the moment and causing the current problem.
The canonical way of doing this is to create a simple server side file, or API, that the client loads the first time the client pages are rendered. That API exposes a simple JSON dictionary of application settings, like this;
This is actually useful, as it creates an extensible mechanism to easily add appSettings in the future. I think it's highly likely to add an "applicationTitle", "applicationLogo", and similar too.
On the react side of things, I'm less certain how to achieve this as I'm not used to writing React code yet. What we want to do really, is fetch this JSON into a constant, that is then available globally throughout the client code. For this part I used Chat GeePeeTee (!) and it suggests about using createContext(), then useEffect() to do a fetch on
/api/appSettings
, and thenuseState
or something along those lines. I don't truely understand the suggestion there, I'd need to play around with that.What this change gives us
This change creates a new serverside API endpoint called
/api/appSettings
on the frontend code, that we can use to validate that this approach hopefully works. The values are not yet used in client code anywhere.Other information:
env
settings entirely from next.config.js`.