NODE_ENV exposed to the client? Is that okay?

I'm getting ready to test a live app using the t3 stack but basically I want my api routes to switch between localhost for dev and the actual url for live testing. the env.mjs puts the NODE_ENV as a server variable and I'm not sure why that is the case below is the code that I'm referring to
import { z } from "zod";
import { createEnv } from "@t3-oss/env-nextjs";

export const env = createEnv({
/**
* Specify your server-side environment variables schema here. This way you can ensure the app
* isn't built with invalid env vars.
*/
server: {
DATABASE_URL: z.string().url(),
DIFF_BOT: z.string(),
OPEN_AI: z.string(),
NODE_ENV: z.enum(["development", "test", "production"]),
STRIPE_SECRET_KEY: z.string(),
STRIPE_WEBHOOK_SECRET: z.string(),
SUPABASE_SECRET_KEY: z.string(),
RESEND_KEY: z.string(),
},

/**
* Specify your client-side environment variables schema here. This way you can ensure the app
* isn't built with invalid env vars. To expose them to the client, prefix them with
* `NEXT_PUBLIC_`.
*/
client: {
NEXT_PUBLIC_SUPABASE_URL: z.string().min(1),
NEXT_PUBLIC_ANON_KEY: z.string().min(1),
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY: z.string(),
NEXT_PUBLIC_PROD_URL: z.string(),
},

/**
* You can't destruct `process.env` as a regular object in the Next.js edge runtimes (e.g.
* middlewares) or client-side so we need to destruct manually.
*/
runtimeEnv: {
DATABASE_URL: process.env.DATABASE_URL,
NODE_ENV: process.env.NODE_ENV,
NEXT_PUBLIC_SUPABASE_URL: process.env.NEXT_PUBLIC_SUPABASE_URL,
NEXT_PUBLIC_ANON_KEY: process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY,
DIFF_BOT: process.env.DIFF_BOT,
OPEN_AI: process.env.OPEN_AI,
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY:
process.env.NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY,
STRIPE_SECRET_KEY: process.env.STRIPE_SECRET_KEY,
STRIPE_WEBHOOK_SECRET: process.env.STRIPE_WEBHOOK_SECRET,
SUPABASE_SECRET_KEY: process.env.SUPABASE_SECRET_KEY,
NEXT_PUBLIC_PROD_URL: process.env.NEXT_PUBLIC_PROD_URL,
RESEND_KEY: process.env.RESEND_KEY,
},
});
import { z } from "zod";
import { createEnv } from "@t3-oss/env-nextjs";

export const env = createEnv({
/**
* Specify your server-side environment variables schema here. This way you can ensure the app
* isn't built with invalid env vars.
*/
server: {
DATABASE_URL: z.string().url(),
DIFF_BOT: z.string(),
OPEN_AI: z.string(),
NODE_ENV: z.enum(["development", "test", "production"]),
STRIPE_SECRET_KEY: z.string(),
STRIPE_WEBHOOK_SECRET: z.string(),
SUPABASE_SECRET_KEY: z.string(),
RESEND_KEY: z.string(),
},

/**
* Specify your client-side environment variables schema here. This way you can ensure the app
* isn't built with invalid env vars. To expose them to the client, prefix them with
* `NEXT_PUBLIC_`.
*/
client: {
NEXT_PUBLIC_SUPABASE_URL: z.string().min(1),
NEXT_PUBLIC_ANON_KEY: z.string().min(1),
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY: z.string(),
NEXT_PUBLIC_PROD_URL: z.string(),
},

/**
* You can't destruct `process.env` as a regular object in the Next.js edge runtimes (e.g.
* middlewares) or client-side so we need to destruct manually.
*/
runtimeEnv: {
DATABASE_URL: process.env.DATABASE_URL,
NODE_ENV: process.env.NODE_ENV,
NEXT_PUBLIC_SUPABASE_URL: process.env.NEXT_PUBLIC_SUPABASE_URL,
NEXT_PUBLIC_ANON_KEY: process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY,
DIFF_BOT: process.env.DIFF_BOT,
OPEN_AI: process.env.OPEN_AI,
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY:
process.env.NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY,
STRIPE_SECRET_KEY: process.env.STRIPE_SECRET_KEY,
STRIPE_WEBHOOK_SECRET: process.env.STRIPE_WEBHOOK_SECRET,
SUPABASE_SECRET_KEY: process.env.SUPABASE_SECRET_KEY,
NEXT_PUBLIC_PROD_URL: process.env.NEXT_PUBLIC_PROD_URL,
RESEND_KEY: process.env.RESEND_KEY,
},
});
If I just make NODE_ENV public will I cause any problems?
11 Replies
barry
barry9mo ago
It's a server variable because it's not prefixed? Simple as that
rovrav
rovrav9mo ago
yes, but is there a reason why it's made into a server variable? Right now I have a basic .env file but I'm trying to figure out if I have a env.development and env.production to separate out the url link to call an api route I want to point the api route to localhost:3000 as the base url and thisismyurl.com for production is that best done in a bifurcated env files? or just changing the NODE_ENV to be accessible from the client
rovrav
rovrav9mo ago
Configuring: Environment Variables
Learn to add and access environment variables in your Next.js application.
conniehunt
conniehunt9mo ago
const localURL = process.env.NEXT_PUBLIC_LOCAL_URL;
const prodURL = process.env.NEXT_PUBLIC_VERCEL_URL;

export const baseURL =
process.env.NODE_ENV === 'development' ? localURL : prodURL;
const localURL = process.env.NEXT_PUBLIC_LOCAL_URL;
const prodURL = process.env.NEXT_PUBLIC_VERCEL_URL;

export const baseURL =
process.env.NODE_ENV === 'development' ? localURL : prodURL;
Is this what you need?
rovrav
rovrav9mo ago
Not sure if this is the Client side, but if so I'm not sure that process.env.NODE_ENV will work but correct me if I'm wrong
conniehunt
conniehunt9mo ago
sorry i just edited, just use process.env.NODE_ENV. it is provided out of the box by next
rovrav
rovrav9mo ago
the problem with that example is that process.env.NODE_ENV can't be accessed from the client side because it's not prefixed with NEXT_PUBLIC
owenwexler
owenwexler9mo ago
Next API routes are considered server-side code and therefore can access server-side environment variables. This can be verified by console.logging process.env.NODE_ENV in a NextJS API route. The way I handle switching between the localhost url for dev and the production url for prod is to make a NEXT_PUBLIC_HOST_URL environment variable myself but this can also be handled conditionally using the NODE_ENV variable.
rovrav
rovrav9mo ago
The only solution I found was making an .env.development and .env.production and setting the host url that way. Can you use conditional logic in a .env file that would check NODE_ENV first then set NEXT_PUBLIC_HOST? How will you call the api route without knowing the host url to even check the NODE_ENV for setting?
owenwexler
owenwexler9mo ago
.env or .env.local would be how you set any environment variables in development. Have you tried a test deployment to your infrastructure of choice? I use DigitalOcean App Platform and they have a form for entering production environment variables before build, and I can imagine Vercel and others have something similar. As for using NODE_ENV to determine the host URL, that can be handled conditionally not in an environment variable but in your backend code by something like const url = process.env.NODE_ENV === ‘production ? ‘Prod URL’ : ‘DEV URL’; conditionals don’t work in environment variables as .env is just a bash file that doesn’t recognize JS. But also if you are using Next API routes you don’t need a host URL, just call ‘/api/foo’ or whatever.
Hope this helps.
rovrav
rovrav9mo ago
I'm using vercel and vercel has an option to specify stating which env variables to use whether it's for production, testing or development. I did not know that you did not need a host url to call a nextJS api route. I've been putting the entire url when calling a nextJS api route this whole time. below is what I've been trying to do and figure out
const API_BASE_URL = process.env.NEXT_PUBLIC_API_BASE_URL;

fetch(`${API_BASE_URL}/api/user`)
.then(response => response.json())
.then(data => console.log(data));
const API_BASE_URL = process.env.NEXT_PUBLIC_API_BASE_URL;

fetch(`${API_BASE_URL}/api/user`)
.then(response => response.json())
.then(data => console.log(data));
but turns out you can just do this
fetch("/api/user")
.then(response => response.json())
.then(data => console.log(data));
fetch("/api/user")
.then(response => response.json())
.then(data => console.log(data));