> ## Documentation Index
> Fetch the complete documentation index at: https://docs.getmilana.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Privacy Options

> Full reference for all privacy configuration options available in the Milana SDK.

All options are nested under `options.privacy` when calling `init()` or configuring `MilanaProvider`. Every option is optional and falls back to the default value shown.

For an introduction to privacy controls and usage examples, see the [Privacy Controls](/guides/privacy) guide.

<Note>
  Selector-based privacy options require matching against elements while the page is being recorded. Prefer simple, specific selectors over complex selectors (deep descendant chains, `:has()`, broad attribute matches).
</Note>

<ParamField path="privacy.maskingLevel" type="&#x22;normal&#x22; | &#x22;high&#x22; | &#x22;xhigh&#x22;" default="normal">
  Sets a baseline for how aggressively Milana masks text content and form input values, layered underneath the per-element controls below. Raise it when you want to mask all text and input values by default and reveal only known-safe elements with `unmaskClass` or `unmaskSelector`. Note that session analysis will not be able to flag several classes of issues if the masking level is too high.

  | Level    | Input values                       | DOM text                           |
  | -------- | ---------------------------------- | ---------------------------------- |
  | `normal` | Masked only when explicitly marked | Masked only when explicitly marked |
  | `high`   | **All** masked                     | Masked only when explicitly marked |
  | `xhigh`  | **All** masked                     | **All** masked                     |

  At `normal` (the default), only elements you explicitly mark — via the classes and selectors below, or the always-masked input types — are masked.
</ParamField>

<ParamField path="privacy.blockClass" type="string | RegExp" default="milana-block">
  Elements with this CSS class are blocked — their content is replaced with a blank placeholder and never sent to Milana. Accepts a plain string class name or a regular expression to match multiple classes.
</ParamField>

<ParamField path="privacy.blockSelector" type="string | null" default="null">
  A CSS selector that identifies additional elements to block. Use this alongside `blockClass` for elements you cannot annotate with a class, for example third-party widgets: `'[data-private], .stripe-payment-form'`.
</ParamField>

<ParamField path="privacy.ignoreClass" type="string" default="milana-ignore">
  Elements with this class are not interacted with in the recording. Mouse events and keyboard input on these elements are omitted.
</ParamField>

<ParamField path="privacy.ignoreSelector" type="string | null" default="null">
  A CSS selector that identifies additional elements to ignore for interaction recording.
</ParamField>

<ParamField path="privacy.maskTextClass" type="string" default="milana-mask">
  Text content inside elements with this class is replaced with masked placeholders in the recording. By default, Milana masks by replacing each character with `*`. Set `shouldUseLayoutPreservingMasking` to use width-matched placeholders that reduce replay layout shifts.
</ParamField>

<ParamField path="privacy.maskInputClass" type="string" default="milana-mask">
  Input values inside elements with this class (or any ancestor with this class) are masked. Applies to `<input>`, `<select>`, `<textarea>`, and `<option>` elements.
</ParamField>

<ParamField path="privacy.maskInputTypes" type="object" default="{}">
  Additional `input[type]` values to always mask, regardless of class or masking level. `password`, `tel`, and `email` — are always masked.

  To also always-mask number fields:

  ```javascript theme={null}
  maskInputTypes: {
    number: true
  }
  ```
</ParamField>

<ParamField path="privacy.maskSelector" type="string | null" default="null">
  A CSS selector identifying elements whose text content **and** input values are always masked, at any masking level — the selector-based equivalent of applying both `maskTextClass` and `maskInputClass`. Use it for sensitive regions you cannot annotate with a class. Explicit masks always take precedence over `unmaskClass` and `unmaskSelector`.
</ParamField>

<ParamField path="privacy.unmaskClass" type="string" default="milana-unmask">
  Elements with this CSS class are recorded in the clear when `maskingLevel` would otherwise mask them. Use it for known-safe UI such as navigation, buttons, headings, and labels.

  This option only reveals values masked by `maskingLevel`. It has no effect at `normal`, and it never overrides explicit masks, blocked elements, or always-masked input types. Setting a custom class replaces the default `milana-unmask` class. Set it to an empty string (`""`) to disable class-based unmasking.
</ParamField>

<ParamField path="privacy.shouldUseLayoutPreservingMasking" type="boolean" default="false">
  Uses width-matched placeholders for masked text and masked input values, so masked recordings are less likely to re-wrap text and shift replay layout. This changes how masked content is rendered, not which content is masked.

  It is recommended to enable this for applications that mask long text, especially when using `high` or `xhigh` masking. Password fields continue to use fixed `*` masking because browsers render them as bullets.

  <Note>
    Layout-preserving masking may preserve approximate word widths, hyphen positions, and line breaks. Use the `milana-block` class when an element should be recorded as a blank placeholder instead.
  </Note>
</ParamField>

<ParamField path="privacy.unmaskSelector" type="string | null" default="null">
  A CSS selector identifying elements to reveal when a masking level would otherwise mask them — input values under `high`/`xhigh`, and DOM text under `xhigh`. Matching elements and their subtrees are recorded in the clear.

  This option has the same semantics and precedence as `unmaskClass`. It only reveals values masked by `maskingLevel`, has **no effect** at `normal` (a warning is logged if it is set), and never overrides:

  * explicit masks (`maskSelector`, `maskTextClass`, `maskInputClass`)
  * blocked elements (`blockClass`, `blockSelector`)
  * always-masked input types (`password`, `tel`, `email`, and any added via `maskInputTypes`)
</ParamField>

<ParamField path="privacy.shouldTrackQueryParams" type="boolean" default="true">
  Whether URL query parameters are recorded when the user navigates. Set to `false` to strip all query strings from recorded URLs entirely.
</ParamField>

<ParamField path="privacy.queryTrackingParamsDenyList" type="RegExp[]" default="[]">
  Additional patterns to redact from recorded URLs. The value of any matching query parameter is replaced with `--redacted--` in the recording.

  These patterns extend the built-in denylist — they do not replace it. The built-in denylist redacts the following parameter names by default:

  | Pattern       | Matches                         |
  | ------------- | ------------------------------- |
  | `/^jwt$/i`    | `jwt`                           |
  | `/^code$/i`   | `code`                          |
  | `/token/i`    | any param containing `token`    |
  | `/password/i` | any param containing `password` |
  | `/secret/i`   | any param containing `secret`   |
  | `/key/i`      | any param containing `key`      |
  | `/auth/i`     | any param containing `auth`     |
  | `/nonce/i`    | any param containing `nonce`    |
  | `/csrf/i`     | any param containing `csrf`     |

  To add your own patterns:

  ```javascript theme={null}
  queryTrackingParamsDenyList: [
    /^session_id$/i,
    /^invite_token$/i
  ]
  ```
</ParamField>
