Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Runtime app settings for frontend service #243

Closed
wants to merge 2 commits into from

Conversation

jamesread
Copy link
Collaborator

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

Note: After being built, your app will no longer respond to changes to these environment variables. For instance, if you use a Heroku pipeline to promote slugs built in one environment to another environment, or if you build and deploy a single Docker image to multiple environments, all NEXT_PUBLIC_ variables will be frozen with the value evaluated at build time, so these values need to be set appropriately when the project is built. If you need access to runtime environment values, you'll have to setup your own API to provide them to the client (either on demand or during initialization).

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:

xwin jamesread@mindstorm: grep -r WAFFLES dist/apps/frontend/
dist/apps/frontend/.next/required-server-files.json:{"version":1,"config":{"env":{"isBillingEnabled":"false","isGeneral":"true","frontendUrl":"I_LIKE_WAFFLES"},"

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;

{
    "isBillingEnabled": true,
    "isGeneral": true,
    "frontendUrl": "http://postiz.example.com:4200",
}

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 then useState 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:

Copy link

vercel bot commented Sep 17, 2024

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
gitroom ❌ Failed (Inspect) Sep 24, 2024 1:04am
1 Skipped Deployment
Name Status Preview Comments Updated (UTC)
postiz ⬜️ Ignored (Inspect) Visit Preview Sep 24, 2024 1:04am

@jamesread jamesread added the type: feature-request New feature or request label Sep 17, 2024
@jamesread jamesread mentioned this pull request Sep 17, 2024
1 task
@jamesread
Copy link
Collaborator Author

Closing, as we found a better way to do this, getting the variables from server context at runtime! :-) Thanks @nevo-david !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: feature-request New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant