Source maps
Upload source maps to your node so stack traces show the original file, line and function — and what has and has not been verified.
On this page
Production JavaScript is minified, so a raw stack trace points at index-4f2a1c.js:1:48213. With source maps uploaded to your node, Belvador shows the original file, line, function and surrounding code. Maps stay on your node; they are never published with your site.
How it works#
During the build,
sentry-cli sourcemaps injectwrites a Debug ID into each JavaScript file and its.mapfile.You deploy the injected JavaScript files — without the
.mapfiles.CI uploads the
.mapfiles to your node with an upload token.When an error arrives, the SDK has attached the Debug IDs of the files in its stack. Your node finds the matching maps and restores the original frames.
Frames that could not be resolved show Minified in the stack trace.
Before you start#
A project and the build output folder, for example
./dist.The same
releasevalue in the SDK'sinitand in the upload, for example the commit SHA.An upload token: Project settings → Upload tokens → New upload token. It is shown once, valid for 365 days, limited to source-map uploads for this project and to 60 requests per hour. Store it as a CI secret named
BELVADOR_UPLOAD_TOKEN. Creating and revoking tokens asks for your authenticator code.
Option A — sentry-cli (recommended)#
Belvador's edge accepts sentry-cli's upload API. Run this in CI after the build, before deploying:
export SENTRY_URL=https://edge.belvador.devexport SENTRY_AUTH_TOKEN="$BELVADOR_UPLOAD_TOKEN"export SENTRY_ORG=belvador SENTRY_PROJECT=<project-slug>npx @sentry/cli sourcemaps inject ./distnpx @sentry/cli sourcemaps upload --release "$RELEASE" ./distProject settings → Upload tokens shows the same commands with your project's address filled in. $RELEASE must be the value you pass as release in init.
Option B — upload a tarball#
Without sentry-cli's upload command, inject Debug IDs, pack the maps and post them:
npx @sentry/cli sourcemaps inject ./dist(cd dist && find . -name '*.map' | tar -czf ../sourcemaps.tgz -T -)curl -fsS -X POST "https://edge.belvador.dev/n/<node-id>/upload/sourcemaps?project=<project-id>&release=$RELEASE" \ -H "Authorization: Bearer $BELVADOR_UPLOAD_TOKEN" \ --data-binary @sourcemaps.tgzThe app shows this command with your node and project already filled in.
Bundler plugins#
Sentry's bundler plugins (Vite, webpack, esbuild, Rollup) use the same upload API as sentry-cli, so they can upload to Belvador when pointed at https://edge.belvador.dev with your upload token. The edge implements the sentry-cli and tarball paths shown on this page; with a plugin, check the result with a test error.
Limits#
| Limit | Value |
|---|---|
| One source map file | 10 MiB |
| Files per upload | 1,000 |
| Unpacked tarball | 64 MiB |
| Requests per token | 60 per hour |
| How long maps are kept | 90 days after they were last used |
Do not deploy .map files#
Remove .map files from what you deploy, or configure your host not to serve them. Anyone who can download them can read your original source.
Check that it works#
Build, inject, upload and deploy one release.
Trigger a test error in that release.
Open the issue: frames show your original file names and lines, and Minified is gone.
If frames stay minified:
the
releaseininitdiffers from the uploaded one;the deployed JavaScript is not the injected build —
injectmust run before you deploy, on the same files;the upload failed: check the CI log for
401(wrong or revoked token) or413(file too large);the token expired after 365 days.
Posts on this topic
All posts- Production source maps with Vite: what each setting really shipsVite sourcemap false, true and hidden compared on one build: what ships, what a stack frame shows, and how to get readable stacks without public maps.
- Cursor and production errors: Debug Mode vs what users hitDebugging production errors with Cursor: when Debug Mode helps, why source maps fix locations but not messages, and a rule that starts from the stack.
- Lovable app shows a blank page: find the cause in the consoleLovable app blank or frozen after publishing? Read the first console error to tell five causes apart, fix each one, and give Lovable the evidence it needs.
Spotted something wrong or missing? Tell us: hello@belvador.dev