Skip to content

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.

Markdown
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#

  1. During the build, sentry-cli sourcemaps inject writes a Debug ID into each JavaScript file and its .map file.

  2. You deploy the injected JavaScript files — without the .map files.

  3. CI uploads the .map files to your node with an upload token.

  4. 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 release value in the SDK's init and 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.

Belvador's edge accepts sentry-cli's upload API. Run this in CI after the build, before deploying:

Terminal
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" ./dist

Project 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:

Terminal
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.tgz

The 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#

LimitValue
One source map file10 MiB
Files per upload1,000
Unpacked tarball64 MiB
Requests per token60 per hour
How long maps are kept90 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#

  1. Build, inject, upload and deploy one release.

  2. Trigger a test error in that release.

  3. Open the issue: frames show your original file names and lines, and Minified is gone.

If frames stay minified:

  • the release in init differs from the uploaded one;

  • the deployed JavaScript is not the injected build — inject must run before you deploy, on the same files;

  • the upload failed: check the CI log for 401 (wrong or revoked token) or 413 (file too large);

  • the token expired after 365 days.

Posts on this topic

All posts

Spotted something wrong or missing? Tell us: hello@belvador.dev