DEV3 Technologies home

DEV3 Developer Forum

How do I make sure server code and secrets never end up in the client bundle in Next.js?

Next.js helpSolved0 views
dev3 ·

We have a lib/db.ts with the connection string and an admin API key. A teammate imported it into a client component by mistake. How do we prevent this class of bug?

#nextjs#security#server-only

0

1 reply

dev3 · Accepted answer

Use the server-only package. Importing a module that contains it from client code fails the build.

npm install server-only
// lib/db.ts
import "server-only";
import { MongoClient } from "mongodb";

export const client = new MongoClient(process.env.MONGODB_URI!);

If any "use client" file (directly or transitively) imports lib/db.ts, next build stops with an error that names the import chain. The opposite, client-only, guards browser-only code.

Other safeguards

  1. Do not prefix secrets with NEXT_PUBLIC_.
  2. Return DTOs, not raw database rows, from server components and actions. Whatever you pass as props to a client component is serialised into the page payload and visible in the browser.
  3. React offers experimental_taintObjectReference and experimental_taintUniqueValue (behind an experimental flag) to block accidental passing of sensitive objects or tokens.
  4. Check authorisation in every server action and route handler. Actions are public endpoints; hiding the button is not security.
  5. Put a data access layer in one folder (for example lib/data/*) that always asks "who is the current user?" before querying.

Verify

Search the build output for secrets:

grep -r "sk_live" .next/static || echo "clean"

Pitfall: a barrel file (index.ts) that re-exports both server and client helpers makes it easy to pull server code into the browser. Import from specific files instead.

0

Your reply

Every post is reviewed by DEV3 before it appears. Usually reviewed within 24 hours.

Markdown supported. Use ``` for code blocks. Images are not allowed.