Enable Readable Stack Traces
Learn how to upload source maps to Sentry so your stack traces show real source code instead of minified output.
Step 5 of 5 (optional)
Optional step
You've already set up distributed tracing across your stack in the previous steps. This step is an optional enhancement — worth doing, but not required.
When you ship JavaScript to production, your code is transformed — bundled, minified, and sometimes transpiled — to make it smaller and faster in the browser. That transformation makes stack traces unreadable: instead of the line of code that failed, you see something like a.b.c at index-J_blQJy.js:1:21834.
Source maps are the bridge back. They tell Sentry how to map the minified output to your original source. In this step, you'll generate source maps for the frontend app, upload them to Sentry, and trigger another error to see the difference.
The sample frontend app uses Vite as its build tool, and the Sentry Vite plugin both generates source maps and uploads them as part of your production build.
Using a different bundler? Use the Sentry Wizard to configure source maps for webpack, Rollup, esbuild, Next.js, and others, then skip to step 3.
In the tracing-tutorial-frontend project folder, install the plugin as a dev dependency:
npm install @sentry/vite-plugin --save-dev
npm install @sentry/vite-plugin --save-dev
yarn add @sentry/vite-plugin --dev
pnpm add @sentry/vite-plugin --save-dev
To upload source maps, the plugin needs an auth token — a secret key that tells Sentry the upload is coming from you. You'll keep this token in a separate file instead of writing it directly into your code, so it stays private.
The Sentry Vite plugin automatically reads your token from a file named exactly .env.sentry-build-plugin. Create that file now:
In the root of the
tracing-tutorial-frontendfolder (the same folder that containspackage.json), create a new file named exactly.env.sentry-build-plugin— including the leading dot.Add your auth token to the file, using the snippet below. Replace the placeholder with the token you generated above:
.env.sentry-build-pluginCopiedSENTRY_AUTH_TOKEN=___ORG_AUTH_TOKEN___SENTRY_AUTH_TOKEN=___ORG_AUTH_TOKEN___Save the file. The sample project's
.gitignorealready lists.env.sentry-build-plugin, so your token won't be committed to git — keep it that way. Auth tokens should never be shared or pushed to a repository.
Next, tell the plugin which Sentry organization and project to upload your source maps to. You'll need two values, both of which are slugs — the short, lowercase names Sentry uses in URLs.
Here's how to find each one in Sentry:
- Organization slug: look at your Sentry URL — it's the part right before
.sentry.io. For example, inhttps://acme-inc.sentry.io/, the organization slug isacme-inc. You can also find it under Settings > General Settings. - Project slug: in the left sidebar, go to Settings > Projects, then click the frontend project you created earlier (not the backend one). The project slug is shown at the top of that project's settings page and in the page's URL.
Now open vite.config.js and add sentryVitePlugin as shown below, replacing ___ORG_SLUG___ and ___PROJECT_SLUG___ with the two values you just found:
vite.config.jsimport { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import { sentryVitePlugin } from "@sentry/vite-plugin";
export default defineConfig({
build: {
sourcemap: true,
},
plugins: [
react(),
sentryVitePlugin({
org: "___ORG_SLUG___",
project: "___PROJECT_SLUG___",
}),
],
server: {
port: 3000,
},
});
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import { sentryVitePlugin } from "@sentry/vite-plugin";
export default defineConfig({
build: {
sourcemap: true,
},
plugins: [
react(),
sentryVitePlugin({
org: "___ORG_SLUG___",
project: "___PROJECT_SLUG___",
}),
],
server: {
port: 3000,
},
});
Your org and project here must point to the same frontend project as the DSN in src/main.jsx. Source maps are matched within a project — if your maps upload to one project but your errors report to another, Sentry won't be able to un-minify them.
By default, the plugin deletes the source map files from your build output after uploading them, so they're not served to your users in production.
Stop your dev server with
Ctrl + Cand create a production build:Copiednpm run buildnpm run buildyarn buildpnpm buildLook for the
Source Map Upload Reportin the output — it confirms the maps reached Sentry and lists each file by debug ID:Copied> Analyzing 2 sources > Adding source map references > Bundling files for upload > Uploaded files to Sentry > Successfully uploaded source maps to Sentry> Analyzing 2 sources > Adding source map references > Bundling files for upload > Uploaded files to Sentry > Successfully uploaded source maps to SentryServe the production build:
Copiednpm run previewnpm run previewyarn previewpnpm previewOpen the app (make sure the backend is still running on
http://localhost:3001), open your browser's dev console, and right-click the reload button, then select 'Empty Cache and Hard Reload' so the new build is served. Then trigger the cross-project error again by clicking the Nonfat Water button.Go to the Issues page in Sentry and open the new issue.
The stack trace should now include file names, function names, line numbers, and the surrounding source code — the actual code that failed, instead of minified output.
Congrats — you've built a fully instrumented fullstack app with Sentry, with cross-project distributed tracing and readable stack traces with source code context.
For ways to take Sentry further — Seer, Session Replay, alerts, dashboards, and more — see What's Next, or head to the Platforms page to set up Sentry on your own project.
Our documentation is open source and available on GitHub. Your contributions are welcome, whether fixing a typo (drat!) or suggesting an update ("yeah, this would be better").