Skip to main content

Advanced Configuration

Stability Tuning

Before capturing page context, the SDK waits for the page to stabilize. This avoids sending incomplete or mid-render snapshots to the AI. The stability system runs a sequence of detection layers, each of which can be toggled independently:
Loading indicators and layout shift layers are disabled by default because many sites have persistent loading animations that would cause unnecessary delays. Enable them if your application uses skeleton screens that reliably disappear.

Enabling Additional Layers

Layer-Specific Configuration

Each layer can be configured individually:

Disabling Stability Checks

For testing or very simple pages, you can disable layers:
Disabling stability layers may cause the AI to receive incomplete page context. Only disable for testing or if you’re certain the page is fully rendered.

After Reload Handling

If your application triggers full page reloads during guided steps, enable the afterReload option to preserve state:

Shadow DOM

The SDK renders all UI inside a Shadow DOM attached to document.body. This means:
  • Your CSS cannot affect Moss UI — styles are fully encapsulated
  • Moss CSS cannot affect your app — no style leakage
  • DOM queries from your app won’t find Moss elementsdocument.querySelector won’t match elements inside the shadow root
If you’re using automated testing tools (Cypress, Playwright, etc.), you’ll need to pierce the shadow DOM to interact with Moss elements. Look for the #moss-shadow-host host element (#clippy-shadow-host in SDK versions up to 0.16).

Content Security Policy (CSP)

If your application uses strict CSP headers, you may need to allow: Example CSP header:

DOM Observation Scope

By default, the SDK observes document.body for changes. To limit observation to a specific part of your page:
This is useful when:
  • Your app has a complex sidebar or header that shouldn’t trigger re-captures
  • You want to reduce noise from unrelated DOM changes
  • The assistant should only help with a specific section of the page

Native Modal Dialogs

When your application opens a native <dialog> with showModal(), the browser makes everything outside the dialog inert — including the Moss widget. The user can’t click the assistant, and an in-progress guide can’t continue. If your application uses showModal(), install the modal dialog escape with the element your integration mounts the widget into:
While a modal dialog is open, the SDK host is temporarily moved into the dialog’s tree (and promoted above it) so the widget stays interactive and keeps its viewport position. When the dialog closes, the host is restored to its original place in the DOM. The returned function uninstalls the listeners and restores the host.
Pass an element your integration owns outright — the container you mounted the Moss widget into. Never pass a node managed by your application’s framework: the escape re-parents the element, which would fight the framework’s own rendering.
Limitations:
  • Dialogs rendered inside shadow roots are not tracked.
  • In browsers without the Popover API, the widget stays interactive but may render clipped inside dialogs that have overflow: hidden or a transform.

Redacting Sensitive Content

Declarative Redaction with data-moss-redact

Mark any HTML element with the data-moss-redact attribute to redact it from all data sent to the Moss backend. This is the simplest way to protect sensitive content.
What gets redacted:
  • Text content — replaced with [REDACTED] in the structured context sent to the backend
  • Sensitive attributesvalue, placeholder, title, alt, aria-label, href, src, and name are all redacted
  • Child elements — all descendants of a redacted element are excluded
Redaction applies to the marked element and any of its ancestors up to 10 levels deep, so you can mark a container to redact everything inside it.

Input Redaction (default on)

All input-type elements — input, textarea, select, and contenteditable regions — have their values redacted by default. What a user has typed into a form never leaves the browser as page context. To opt a specific field out when its content is known to be safe and useful to the assistant (for example, a search box), mark it with data-moss-unredact:
To disable input redaction entirely, set redactAllInputs: false:
Keep redactAllInputs enabled unless you have reviewed every form in your application. With it disabled, typed form values are included in the page context sent to Moss.

Redaction by CSS Selector

If your application already marks sensitive elements for another tool (for example FullStory’s .fs-exclude / .fs-mask classes), reuse those markers instead of adding data-moss-redact everywhere. Elements matching redactionSelectors are redacted identically to data-moss-redact:
data-moss-redact is always recognized regardless of this setting. If an element matches both an allow rule and a redact rule, the redact rule wins.

What redaction covers

Redaction applies to the page text and structure sent as context and to the interaction reports recorded during step-by-step guidance. It does not alter chat messages the user types, screenshots, session recordings, or screen history — disable those features individually if their output is not permitted in your environment.

Programmatic Sanitization

For more complex sanitization logic, use pageSanitizationScript to modify a cloned copy of the DOM before capture:
Both methods only affect what the AI sees. The live DOM is never modified — your users won’t see any changes.

Troubleshooting

Assistant button doesn’t appear

  1. Check the browser console for [MossSDK] errors
  2. Verify applicationId matches a valid application in the Dashboard
  3. Confirm apiUrl is reachable from the browser
  4. Check that your JWT signing key is active and not revoked

”Failed to fetch config” error

  • The SDK couldn’t reach the backend. Check apiUrl and network/CORS settings.
  • If using CSP, ensure connect-src includes the backend URL.

Screenshots are blank or incomplete

  • Try switching screenshotMode to 'viewport'
  • Increase stability.domMutations.quietPeriodMs if the page has slow animations
  • Check if iframes or cross-origin content is blocking capture

Styles conflict with host application

This shouldn’t happen — the SDK uses Shadow DOM isolation. If you see conflicts:
  • Check if your app is using !important on * or body selectors
  • Verify no JavaScript is modifying the shadow root

Debug mode

Enable verbose logging to diagnose issues:
This logs stability layer timing, network requests, context capture details, and API responses to the browser console.