password and authorization, still runs on network requests after your sanitizers.
Sanitizers need a connected domain with Jam installed by the SDK or by script tags.
This sanitizers object uses all four options:
Options
Set only the options you need. Each sanitizer receives a copy of one event. Return the copy, edited or not, to keep it, or returnnull to drop it. Jam reads back only the fields you can change and ignores edits to read-only fields.
(request: NetworkRequest) => NetworkRequest | null
Receives each request. Return
null to drop the request and its response.(response: NetworkResponse) => NetworkResponse | null
Receives the response of each completed fetch and XHR request. Return
null to drop the response headers and body. Jam keeps the request, status, and timing.(message: WebSocketMessage) => WebSocketMessage | null
Receives each text WebSocket message the page sends or receives. Return
null to drop the message. Jam keeps the connection.(log: ConsoleLog) => ConsoleLog | null
Receives each console message and uncaught error. Return
null to drop the log.@jam.dev/recording-links/sdk, or type the whole object as JamSanitizerOptions as in the example above.
Request and response bodies are text, so a sanitizer can parse JSON or match a regular expression. Keep a JSON or form body in its format. Jam’s own redaction of secret keys reads only JSON and form bodies, so it skips a body that a sanitizer turned into other text.
Jam writes console arguments back as JSON, so return values that JSON can hold. Jam replaces an argument such as undefined, a function, or a BigInt with JAM_CUSTOM_SANITIZER_REDACTED.
Jam calls requestSanitizer twice for each fetch and XHR request: when it starts and when it completes. Return the same result both times. To handle kinds of requests differently, check type.
Sanitizers don’t cover WebSocket connection URLs, console stack traces, fetch error messages, or the page URL. Jam’s own redaction still removes secret query parameters from WebSocket URLs.
When a sanitizer fails
Jam replaces the data withJAM_CUSTOM_SANITIZER_REDACTED instead of sending it unsanitized:
- It throws an error: Jam replaces the data the sanitizer covers. That is the URL path, headers, and body of a request or response, the data of a WebSocket message, or the arguments of a log. The method, status, timing, and URL origin stay. If
requestSanitizerthrows, Jam replaces the response too, becauseresponseSanitizercan no longer see the real URL. - It returns nothing or a value that isn’t an object: Jam replaces all the data the sanitizer covers.
- It returns one field with the wrong type: Jam replaces only that field. A wrong
urlalso replaces the response. - It returns a
Promise: Jam replaces the data, because it doesn’t wait for thePromise. Sanitizers must be synchronous. - An option has the wrong type or a misspelled name, for example
requestSanitiser: Jam replaces the data of every request and WebSocket message, or of every log, depending on the option. setSanitizers()gets a misspellednetworkorconsolekey, for exampleconosle: Jam replaces the data of every request, WebSocket message, and log.
Add sanitizers to your site
Pick the method that matches your install:-
SDK: pass the sanitizers to
initialize. -
Script tags: call
window.jam.capture.setSanitizers(sanitizers)in a module script placed right after thecapture.jstag. Jam sends nothing before a recording starts, so this call covers every event.Keep both tagstype="module", in this order, and withoutasync. Module scripts run in document order, socapture.jshas run before your script checks for it. If the error appears, fix the tags before you rely on the sanitizers. A call made while a recording runs covers only the events Jam hasn’t sent yet. To cover every event, call it right aftercapture.js, or use the SDK.
setSanitizers again.
setSanitizers replaces every sanitizer that initialize set, including any that the new call leaves out. Jam doesn’t merge the two. To turn every sanitizer off, call setSanitizers({}). If you pass undefined or null, for example a variable that isn’t set yet, Jam replaces the data of every request and every log.
Jam doesn’t support sanitizers on Google Tag Manager installs. To use sanitizers, install Jam with the SDK or script tags.
Examples
Each example is one function. They are starting points: adapt them to the data your app handles.- Put a network example under
networkand a console example underconsolein your sanitizers object. - Keep helpers such as
PRIVATE_FIELDSoutside the object. - To use two examples for the same option, merge their code into one function.
Network examples
Remove a header
Jam lowercases header names, so match them in lowercase. Jam captures request headers only for fetch requests.responseSanitizer with response.headers.
Mask card numbers in request bodies
This example matches 16-digit card numbers written without spaces or dashes.Remove fields from a JSON body
This example hides the listed fields at any depth. A body that isn’t JSON stays as it is.responseSanitizer with response.body.
Remove a token from the URL
Replacetoken with the name of your query parameter.
Drop requests to an endpoint
Returnnull to drop the request and its response. This example drops every request whose path starts with /api/payments. It parses the URL first, so a query string that mentions the path doesn’t match.
Hide a response body
Jam keeps the request, status, and timing. To drop the response headers as well, returnnull instead.
Console examples
log.args is an array with one value per argument: a string, a number, a boolean, null, an array, or an object. Objects are copies, so editing one doesn’t change your page.
Hide emails
This example converts each argument to JSON, replaces emails, and parses the result. It finds emails in strings and inside objects, including addresses with non-English letters such asjosé@example.com.
Remove fields from logged objects
This example hides the listed fields at any depth in objects and arrays.Drop debug logs
Returnnull to drop a log.

