Skip to content

Upload source maps

Source maps translate generated JavaScript locations into original files, functions and lines. Debug IDs identify the exact emitted bundle independently of its URL or release name.

The browser SDK captures Debug IDs from SDK 2.1.0; see install. Installing the CLI or a bundler plugin alone does not upgrade the browser SDK.

Errors without a Debug ID still match by the SDK’s version and the generated bundle filename, so keep version and the uploaded release version aligned.

Install the published CLI with Node.js 22 or newer, enable external or hidden version 3 source maps in your build, then build and inject:

Terminal window
npm install --save-dev @siteqwality/cli@0.1.4
npm run build
npx siteqwality sourcemaps inject ./dist

Injection adds a Debug ID to each bundle and its map, preserving mapped positions and source content. Deploy the exact injected JavaScript: run signing and integrity generation after injection, and do not minify or rewrite the output afterward.

Inline and indexed maps are unsupported. Injection rejects unsafe paths, symlinks, conflicting IDs and changed previously injected files. Rebuild from clean output when a pair changes.

Keep your API key in the CI secret store. It must have write:rum for uploads and release changes, plus read:rum to list releases. Never embed it in the browser bundle.

Terminal window
export SITEQWALITY_APP_ID='your-application-uuid'
export SITEQWALITY_API_KEY='your-ci-secret'
export SITEQWALITY_RELEASE='web-2026.10.04'
npx siteqwality sourcemaps upload ./dist --delete-after
# Deploy the exact injected files, then record a successful deployment:
npx siteqwality releases deploy "$SITEQWALITY_RELEASE" --env production
npx siteqwality releases list

Upload creates the release if needed and uploads maps in batches of up to 50. Each map is limited to 32 MiB both compressed and inflated. --delete-after removes the local maps only after every upload is confirmed. A failure exits nonzero and must block the deployment. A confirmed upload does not prove symbolication, so check a real error’s original location.

Without a release, uploads use the reserved __debug_id__ release and require Debug IDs. A deployment record does not deploy your site or change the SDK’s version.

Install the published bundler adapters with Node.js 22 or newer:

Terminal window
npm install --save-dev @siteqwality/unplugin@0.1.4

Vite example:

import { defineConfig } from 'vite';
import siteqwality from '@siteqwality/unplugin/vite';
export default defineConfig({
plugins: [siteqwality({ release: 'web-v1', deleteAfter: true })],
});

Equivalent adapters are exported from @siteqwality/unplugin/rollup, /webpack and /esbuild. They use the same CI environment variables. Place the adapter after JavaScript and map transforms. Use upload: false for local injection without upload; it cannot be combined with deleteAfter: true.

Rollup needs external sourcemap: true. webpack supports source-map, hidden-source-map and nosources-source-map. esbuild needs an outdir or outfile and external maps. Vite enables external production maps and does not upload from the development server.

The adapter defines __SQ_RELEASE__; pass that value explicitly as the SDK’s version option in init(). TypeScript applications can declare declare const __SQ_RELEASE__: string. Keep credentials out of compile-time defines. Bundle filenames retain their pre-injection hashes, so generate SRI from final bytes.

Requests use Authorization: Bearer <API_KEY> and Content-Type: application/json, and the routes below are relative to /rum/{app_id}.

  1. Create or reuse a release with POST /releases and {"version":"web-v1"}.
  2. Call POST /releases/web-v1/sourcemaps with the batch shown below.
  3. PUT the exact bytes to each returned data.files[].upload_url within its 300-second lifetime, using every returned header and the declared byte length. Do not send API authorization to storage.
  4. Call POST /sourcemaps/confirm with { "ids": ["returned-upload-uuid"] }.
{
"files": [{
"filename": "assets/main.js.map",
"debug_id": "bf1f8d8f-6ab0-88f3-b53b-f8085758df31",
"size_bytes": 1234,
"content_type": "application/json",
"content_encoding": "gzip"
}]
}

size_bytes is the exact uploaded size, including gzip encoding. Use a byte buffer or Blob so the HTTP client supplies Content-Length, or set it when streaming. URL-encode release versions in path segments. Filenames may include a relative directory, such as assets/main.js.map. Maps are not used until their upload is confirmed.

Symbolication happens when an error is read, so a map uploaded after an error still resolves it, without changing issue grouping. Missing or invalid maps leave generated frames readable. Failed lookups are not cached, while a successful result can be cached for 24 hours.

Check that the deployed bundle is the injected file, the SDK captured its Debug ID, the uploaded map has the same ID, and the upload was confirmed. If source context is absent, ensure the map includes sourcesContent. The API shows one-based line and column numbers.

Keep maps out of public hosting: they can contain your complete source code. Hidden maps avoid a browser source-map URL but still need excluding from deployed assets, or deleting after a confirmed upload. MCP and Connected App responses omit source context and other sensitive occurrence fields.