Skip to content

Ensuring sensitive code is run only server-side with NextJS, where can such code be ran from?

I’m learning NextJS and I’m trying to determine how to layout my project with a clean architecture that’s also secure. However, I’m not sure about where to store code that contains potentially sensitive data (ie. connections to databases, accessing the file system, etc.). I’ve read the docs, but I’m still unsure about this one issue.

In my project layout, I have 2 directories that that relate to this problem: a top level /lib I added and the /pages/api directory that comes baked into every NextJS project.

To my understanding /pages/api NEVER sees the client-side and is hence safe for sensitive code. It should only be used as somewhere to do post, patch, delete, etc. operations. An example of where /pages/api is used would be when you make a post request to the server from a form. You can call an api from this route from ANYWHERE, for example: a form component, the /lib folder, a page in /pages, an external 3rd party api – wherever.

On the other hand, the top level /lib directory, is a place for boilerplate code, carrying out tedious operations such as sorting blog posts into alphabetical order, doing math computations, etc. that’s not necessarily “secret” or sensitive – just long and annoying code. The /lib directory will ALWAYS be seen by the client-side – even if it’s code that’s only called by a server-side method such as getStaticProps().

In short, anything remotely sensitive should always be made as a post, patch, put etc. request to the /pages/api directory, and any long/tedious code that’s not sensitive should be refactored to the /lib directory.

Do I have this all right?



You can do you sensitive stuff in api routes, getServerSideProps, getStaticProps. None of your code in /lib will be seen by the client unless your page actually imports code from there.

Since you were talking about db connections, it’s very unlikely you’d be able to connect to your db from the browser by accident. Almost none of the libraries used to connect to db won’t work from the browser and you also can only access env variables that start with NEXT_PUBLIC_ on the client.

You also need to keep in mind that every file under /api will be an api route, so you should put your helper files inside /lib instead of /api. If you put them under the /api that could lead to security vulnerabilities since anyone can trigger the default exported function of the files under /api.

If you for some reason need to be absolutely certain that some code isn’t bundled to the files that clients will load even if you by accidentally to import it, it can be done with custom webpack config. Note that I’d only look into this option if the code in itself is very sensitive. As in that someone being able to read the code would lead to consequences. Not talking about code doing db queries or anything like that, even if you imported them by accident to client bundles, it wouldn’t pose any threat as the client cannot connect to your database.