In nextjs, does the code for "/api" routes end up in the browser at any point? If so Is there a way to force server-side-only execution?

Viewed 1277

I'm just now realizing this behavior about nextjs env vars here, which is different from how nodejs apps are usually set up:

Note: .env files should be included in your repository, and .env*.local should be in .gitignore, as those files are intended to be ignored. Consider .local files as a good place for secrets, and non-local files as a good place for defaults.

So I'm thinking of restricting myself to using a secret available only at build-time, to be used inside a "backend" /api route.

But do /api routes even behave like true backends? Since nextjs is SSR only when it has to be (?), I presume this /api code can also end up in the browser, therefore exposing the secret? Is there a way to force code to only run server-side and not in-browser? I am new to SSR concepts. My "real" backend won't be up for a while. This is not a hugely important secret, but still. Thx.

1 Answers

API routes won't end up in the client bundle, so any code you put in /pages/api will stay hidden from the user. These routes are meant to be run exclusively on a server environment.

The same concept applies to getStaticProps which only runs on a server during build.

NextJS has a mechanism called "inlined environment variables". Any references to environment variables that start with NEXT_PUBLIC_ will be automatically replaced with their values. So if your local/build/production machine has the variable NEXT_PUBLIC_APPNAME set, NextJS will replace references to process.env.NEXT_PUBLIC_APPNAME with the variable's value.

Alternatively you can define variables in an .env file. These will also be used by your application, and may end up in your client bundle if you reference them in any code that renders on the client (like the JSX in pages/about.js).

Conclusion: secrets should be added to .env, and only be referenced in server-side code like API routes and getStaticProps.

You may also be interested in this tool: https://next-code-elimination.vercel.app/

It lets you verify that your server-side code stays out of the client bundle.

Related