The flag is off by default, so check what turned it on
This is a Next.js-specific fix, not a primer on what source maps are. If you want the why, read Source maps and public exposure in vibe-coded apps first; this note starts from the config.
The concrete risk: if your production build emits client (browser) source maps, every minified .js file on your deployed site ships with a matching .js.map that maps it back to readable source. Anyone who opens DevTools, or just requests the .map URL directly, can read your component names, route structure, client-side API paths, and any comments that survived the build. That is observable from outside, with no login and no tooling beyond a browser.
Here is the part worth getting right, because a lot of advice online is wrong about it. In Next.js, browser source maps are NOT emitted in a production build by default. The flag that controls this is productionBrowserSourceMaps in your next.config file, and its default is false. Next.js disables client maps in production specifically to avoid leaking your source on the client. So if your deployed Next.js app is serving .js.map files, something turned them on. The fix is usually confirming the flag is false and finding what flipped it, not adding a setting that was never there.
- Default behavior: productionBrowserSourceMaps is false, so next build produces no client .js.map files.
- When set to true: Next.js outputs the maps in the same directory as the JavaScript files and serves them automatically when requested.
- This is an information-exposure issue, not a code-execution one. Maps make your client code easier to read; they do not by themselves grant access to anything.
Client maps versus server maps
These two get conflated, and only one of them is served to your visitors.
Client (browser) source maps are the ones that matter here. They sit next to the JavaScript the browser downloads, and if present, the browser (and any visitor) can fetch them from your public URL. This is what productionBrowserSourceMaps controls.
Server source maps are used to make server-side stack traces readable in your logs and error tooling. They are not served to the browser as part of the client bundle, so they are not the public-surface exposure this note is about. Newer Next.js versions have separate handling for server-side maps, but the thing an outside visitor can pull from your URL is the client map. When you read advice that says "Next.js turns off source maps in production," it is talking about the client bundle, which is the correct thing to care about for launch exposure.
- The exposure you can be probed for is the client .js.map sitting beside your client JavaScript.
- A server map that only feeds your own error monitoring is a different concern and not what a public scan or a curious visitor reaches.
- If you keep maps for error monitoring, the goal is to get them to your monitoring tool privately, not to leave them linked from public assets.
Set the config explicitly
The flag lives in next.config, in whichever extension your project uses: next.config.js, next.config.mjs, or next.config.ts. The default already keeps client maps off, but setting it explicitly is worth doing so a future edit or a copied template does not silently flip it.
In next.config.js (CommonJS), the shape is module.exports = { productionBrowserSourceMaps: false }.
In next.config.mjs or next.config.ts (ES modules), it is export default { productionBrowserSourceMaps: false } as the config object, typed with NextConfig in the TypeScript case.
- If you find productionBrowserSourceMaps: true anywhere in your config, that is what is emitting client maps. Set it to false (or remove the line) unless you have a deliberate reason to ship maps publicly.
- Setting it to false matches the default. The value of writing it down is that it survives a teammate or an AI assistant later pasting in a config snippet that enabled it.
- Changing the config is a build-time setting. It only takes effect on the next production build and deploy, so the change is not real until you rebuild and ship.
One trap: a third-party integration can re-enable maps even when your own flag is false. Some error-monitoring setups (for example, a Sentry build wrapper) generate source maps during the build so they can symbolicate stack traces. Confirm such a tool uploads the maps privately and deletes them from the deployed output, rather than leaving .js.map files served from your public URL.
Why AI-built Next.js apps trip this
Since the safe behavior is the default, exposure here usually means a setting or a tool turned maps on, and nobody reviewed the deployed output.
AI-assisted builds optimize for "the page renders." A served .js.map does not break anything visible, so it stays invisible from inside the app. The step that would catch it, looking at what the deployed URL actually serves, is exactly the review step a fast build tends to skip.
- A generated or copied next.config that includes productionBrowserSourceMaps: true, often pasted in to debug a production error and then forgotten.
- A monitoring or build plugin that enables map generation as a side effect, where the maps were meant for the tool but ended up served from the public URL too.
- A deploy where the first working build became the launch URL, so no one checked the deployed assets for .map files before sharing the link.
Verify on the deployed URL, not just in the config
A correct config is necessary but not sufficient. What proves the fix is the deployed site serving no client maps. Run these against your own production URL after you rebuild and deploy.
Open your site, open DevTools, and go to the Network tab. Reload and look at the .js files the browser downloads. With maps off, you should see the .js requests and no accompanying .js.map requests. If the browser is fetching .js.map files, maps are still being served.
Then check directly. Pick a main client bundle URL from the Network tab and request the same path with .map appended, in a clean browser tab or with curl against your own domain only.
Also worth a look: open a deployed .js file and search the end for a sourceMappingURL comment. A line pointing at a .map file is the reference the browser follows, and its presence on the public bundle is the thing to remove.
- Suspicious result: the .map URL returns 200 with JSON that includes a sources or sourcesContent field. That is a live client source map, readable by anyone.
- Safer result: a 404 or your app's not-found page for the .map path, and no .js.map entries in the Network tab. That means the client maps are not being served.
- One caveat, the same one that bites .git checks: some single-page-style setups answer every unknown path with 200 and the index HTML. If the .map URL returns your homepage HTML rather than source-map JSON, that is the fallback, not an exposed map. Read the body, not just the status code.
Where VibeCodeGuard fits, and what it does not prove
VibeCodeGuard's Launch Check verifies .map file absence on your public URL after deploy. It requests the source-map paths from the public surface and flags any client .js.map that returns real source-map content, with severity and fix direction. The point is that you confirm the config change actually took effect on the running deploy, rather than trusting the setting alone. A correct next.config and a stale build that still serves maps are two different states, and only the public URL tells you which one you shipped.
What it does not do is read your next.config or your build pipeline. Deciding whether a given map should exist, and untangling a monitoring plugin that re-enables generation, is work on your own build setup. The scan checks what an outside visitor can reach; it does not inspect your source or your CI.
Next step: grep your next.config for productionBrowserSourceMaps, set it to false (or remove it), rebuild, deploy, then open the Network tab on the live URL and confirm no .js.map is fetched. Run a focused Launch Check against the public URL before sharing it, so a stray source map shows up in your scan and not in someone else's.
A clean map check is one signal, not a guarantee your client code is private. Minified production JavaScript is still downloadable and readable with effort even with no source map, so removing maps raises the cost of inspection rather than hiding your client logic. Never put secrets in client code on the assumption that maps being off keeps them safe; the bundle itself ships to the browser.
> launch check
Scan the public surface before launch.
Get severity, evidence, and practical fix guidance for the checks VibeCodeGuard can run from the outside.