client.mjs, server.mjs, process.env
Can someone please explain the use cases for each? I see that process.env in used in src/utils/trpc.ts. Why not use server.mjs there? In server,mjs we do ...clientEnv which means in server.mjs we have all the env variables. Then when should we use client.mjs?
41 Replies
The env exports dont contain the port or vercel url which is used in that file, please don't make duplicate posts
So if I add them to server.env I can use them?
I don't understand the need for client.mjs if server.mjs has all the env vars we need?
Client only includes what will be exposed client side
So you import it on the client, and server on the server
i can import server on the client and it would still work
Anything not prefixed with NEXT_PUBLIC won't be exposed to the client in production
export const env = { ..._serverEnv.data, ...clientEnv };
That line in server.mjs exposes any NEXT_PUBLIC-prefixed env vars
If you import server envs on the client, server variables will be undefined, and it'll probably error, if not then they will be nothing
How does nextjs know I'm importing server.mjs or client.mjs?
Is everything under "server" considered server-side? What about "api/"?
How does NextJS know which object exposes what env variables?
This might help https://nextjs.org/docs/basic-features/environment-variables
Basic Features: Environment Variables | Next.js
Learn to add and access environment variables in your Next.js application.
It doesn't
But it will expose anything with NEXT_PUBLIC to the client, and anything else plus that to the server
By that logic
If I use import { env } from "../../env/server.mjs";
on the client
Why would it throw an error?
Because the zod parsing would not pass
Which one?
serverSchema?
The server
Why would it not pass?
Isn't it seeing .env?
Because the server-sided environment variables would not exist, since its the client
I see
So how does NextJS defines what is "the client"?
The browser
The react part of the nextjs app
In our file structure, everything in the server folder is not "the client" right?
It depends where its ran from, in this case all that would be server
hmm
what if I need a variables in both under pages/ and under server?
I know now that I cannot use server.mjs on the client side since those .env vars would not be seen by the browser, would it work if I try to use client.mjs under server/ or under api/?
I tried it and it seems to work, but it seems a little unconventional to do that?
Then they should be setup as client variables
Yes they are set up as client vars
Importing client on the server would work but no reason to
but i also need them as server vars
I need the NEXT_PUBLIC_MY_VAR on both pages/ and server/
Client vars will be on both as you showed above
What's the best way to do it? I know process.env.NEXT_PUBLIC_MY_VAR and env.NEXT_PUBLIC_MY_VAR both work
should I import { env } from "../../env/client.mjs";?
On the client yes
You import the appropriate env file for your environment
So you're saying under pages/ I should import import { env } from "../../env/client.mjs";
And under server I should import import { env } from "../../env/server.mjs";
Yep
And API routes
Ok...the reason I'm asking is because I have an object that is shared both by the server and the client
Is there ever a reason to use process.env? Like in src/utils/trpc.ts
Why is that file not using client.mjs or server.mjs?
It's used there because vercel url and port don't always exist and they're not managed by the user
Are VERCEL_URL and PORT and NODE_ENV special variables managed by Vercel?
Yes
Not node env
PORT is managed by vercel?
Yes, they add that
You can also add it in dev if you want but there's the default hard coded in
For NODE_ENV, I didn't specify it in my .env file but it seems to have a value somehow. Does NodeJS do that automatically? Or NextJS? I know that its value is "development" when I run "npm run dev" and "production" after "npm run build"
Node does that
I see
If vercel adds the port
Looking at this http://localhost:${process.env.PORT}
It means vercel uses http://localhost for SSR?
Oh wait nvm
Ny bad
So Vercel uses https://${process.env.VERCEL_URL} for SSR
whereas when developing we use localhost 3000
So I think PORT is managed by us
not Vercel
Oh yeah, that's not used on vercel deployments
In there in case you want to use a custom port while developing
Thank you
I appreciate the clarification