Source maps & releases
Without source maps, a browser stack trace is app.4f2c.js:1:28461. With them, it is
src/checkout/pay.ts:88, with the surrounding lines shown.
Errora symbolicates before grouping, so issues group on stable original frames rather than on bundle hashes that change every deploy.
1. Emit source maps
// vite.config.ts
export default defineConfig({ build: { sourcemap: true } });
// webpack.config.js
module.exports = { devtool: "source-map" };
Next.js: productionBrowserSourceMaps: true in next.config.js.
2. Set a release in the SDK
The release string is the key everything is filed under. It must match exactly between the SDK and the upload.
Sentry.init({
dsn: "…",
release: "web@1.4.2", // same string as the upload below
dist: "prod", // optional, for platforms that build per-distribution
});
3. Upload the artifacts from CI
for map in dist/assets/*.js.map; do
curl -sf -X POST "$ERRORA/api/v1/projects/$PROJECT_ID/release-files" \
-H "Authorization: Bearer $ERRORA_TOKEN" \
-F "release=web@1.4.2" \
-F "name=~/assets/$(basename "${map%.map}")" \
-F "sourcemap=1" \
-F "file=@$map"
done
| Field | Meaning |
|---|---|
release | Required. Must equal the SDK's release. |
name | Required. The artifact's URL path. ~/ stands for "any host", which is what you want unless you serve from one fixed origin. |
dist | Optional distribution label; must match the SDK's dist. |
sourcemap | Mark the upload as a map rather than a bundle. |
file | The file itself, multipart/form-data. |
Uploading the same (release, dist, name) again replaces it, so re-running a deploy is safe.
Use a personal access token for CI — never a user's session token.
GitLab CI example
upload-sourcemaps:
stage: deploy
script:
- npm run build
- |
for map in dist/assets/*.js.map; do
curl -sf -X POST "$ERRORA/api/v1/projects/$PROJECT_ID/release-files" \
-H "Authorization: Bearer $ERRORA_TOKEN" \
-F "release=web@$CI_COMMIT_SHORT_SHA" \
-F "name=~/assets/$(basename "${map%.map}")" \
-F "sourcemap=1" -F "file=@$map"
done
…with release: \web@$`` in the SDK init.
4. Verify
Trigger an error in the deployed build and open the issue. Frames should show your original file, line, column and source context. The artifacts you uploaded are listed at:
GET /api/v1/projects/{project_id}/release-files?release=web@1.4.2&dist=
POST /api/v1/projects/{project_id}/release-files
GET /api/v1/projects/{project_id}/release-files/{id}
DELETE /api/v1/projects/{project_id}/release-files/{id}
How it works
For each minified frame, Errora finds the artifact by name, follows the map to the original
file, line and column, and attaches the surrounding source lines when the map contains
sourcesContent. Keep sourcesContent in your maps: without it you get the right filename
and line, but no code context.
Should the maps be public?
No. Upload them to Errora and do not deploy .map files to your web server (or serve
them behind auth). Errora reads them server-side; your users never need them.
Troubleshooting
| Symptom | Cause / fix |
|---|---|
| Frames still minified | release mismatch between SDK and upload — the most common cause by far |
| Right file, no source context | The map has no sourcesContent |
| Some frames resolved, some not | Only some bundles were uploaded; loop over all maps, including vendor chunks |
| Wrong lines | The uploaded map belongs to a different build than the deployed bundle — upload from the same CI job that built it |
401 on upload | The token is missing, or lacks access to that project |