Skip to content

Configuration

Set all options via window.Do11yConfig using an inline script or a separate config file, or via meta tags. When both are present, meta tags take precedence over window.Do11yConfig, which takes precedence over the defaults.

Destination

Do11y supports three destinations for event data: Supabase (default), generic HTTP, and OTLP via the OpenTelemetry Browser SDK.

OptionDefaultDescription
destination'supabase'Where to send events. 'supabase', 'http', or 'otlp'.

Supabase (default)

The supabase destination is a preset over the http destination. It automatically configures the endpoint, headers, and body transform for Supabase's REST API.

OptionDefaultDescription
supabaseUrl''Your Supabase project URL. For example: https://abc123.supabase.co
supabaseKey''Publishable key. For example: sb_publishable_1234567890
supabaseTable'do11y_events'Name of the table to insert events into.

Under the hood, this sets:

  • endpoint to <supabaseUrl>/rest/v1/<supabaseTable>
  • headers with Supabase REST headers
  • bodyTransform to (events) => events.map(e => ({ payload: e }))

HTTP

To send events to a HTTPS endpoint, set destination to 'http', and provide the endpoint and optional headers and bodyTransform. Do11y sends the events as a JSON array with Content-Type: application/json.

OptionDefaultDescription
endpoint''Full URL to POST events to. Must be HTTPS.
headers{}Custom headers to include (for example, authorization).
bodyTransformundefinedOptional function to transform the event array before sending. Receives the events array and returns what you want to serialize as JSON. Example: (events) => ({ events }).

OTLP (OpenTelemetry Protocol)

To send events to an OpenTelemetry-compatible backend, set destination to 'otlp'.

NOTE

If you use the OTLP destination, your Do11y implementation relies on external dependencies. Do11y dynamically loads the OpenTelemetry Browser SDK via a CDN, and creates a standard LoggerProviderBatchLogRecordProcessorOTLPLogExporter pipeline, and sends events as properly-structured OTel LogRecords.

OptionDefaultDescription
otelSdkEndpoint''Your OTLP collector URL. For example: https://otlp.grafana.com/otlp. The /v1/logs path is appended automatically.
otelSdkHeaders{}Custom headers for the OTLP request (for example, authorization).
otelSdkServiceName'do11y'Value of the service.name resource attribute.
otelSdkResourceAttributes{}Extra resource attributes to attach to every exported LogRecord.
otelSdkCdnUrl'https://esm.sh/'CDN base URL for dynamically importing OTel SDK packages. Override for self-hosted or mirrored packages.
useOtelBrowserInstrumentationsfalseWhen true, also registers standard OTel Browser instrumentations (navigation, user action, web vitals, errors).

CORS and the OTel Collector

OTLP endpoints are designed for backend-to-backend communication and most cloud services (Grafana, Datadog, etc.) don't return CORS headers, which means browsers block cross-origin requests directly to them.

The standard OTel solution is to run a local OpenTelemetry Collector that accepts CORS requests from your docs domain and forwards them to your backend. You can configure the collector with a CORS HTTP receiver:

yaml
receivers:
  otlp:
    protocols:
      http:
        cors:
          allowed_origins:
            - https://docs.example.com
            - https://your-docs-domain.com
            - http://localhost:*
          allowed_headers:
            - Content-Type
            - Authorization

exporters:
  otlphttp:
    endpoint: https://otlp.grafana.com/otlp

service:
  pipelines:
    logs:
      receivers: [otlp]
      exporters: [otlphttp]

Set otelSdkEndpoint to your collector (for example, https://collector.example.com:4318). The collector handles authentication and forwarding to your cloud backend.

If you cannot run a collector, use a lightweight CORS proxy (such as cors-anywhere or a Cloudflare Worker) that adds the required headers.

Behavior

OptionDefaultDescription
debugfalseLog events to the browser console.
flushInterval5000Milliseconds between batch flushes.
maxBatchSize10Events queued before forcing a flush.
trackOutboundLinkstrueTrack clicks on external links.
trackInternalLinkstrueTrack clicks on internal links.
trackScrollDepthtrueTrack scroll depth thresholds.
scrollThresholds[25, 50, 75, 90]Scroll percentages to record.
trackSectionVisibilitytrueTrack which headings users actually read (via IntersectionObserver).
sectionVisibleThreshold3Minimum seconds a section must be visible before recording.
trackTabSwitchestrueTrack code language/framework tab switches.
trackTocClickstrueTrack on-page table of contents clicks.
trackExpandCollapsetrueTrack expand/collapse interactions (details, accordions).
trackFeedbacktrueTrack "Was this helpful?" feedback widget clicks.
allowedDomainsnullRestrict which domains may send data. Set to null to allow any.
respectDNTtrueHonor the browser's Do Not Track setting.
maxRetries2Retry count for failed requests.
retryDelay1000Base delay between retries in milliseconds (doubles each attempt).
rateLimitMs100Minimum gap between events of the same type.

Framework

Set framework to auto-configure CSS selectors for your documentation platform:

ValueFramework
'mintlify'Mintlify (default)
'docusaurus'Docusaurus
'nextra'Nextra
'mkdocs-material'MkDocs Material
'vitepress'VitePress
'starlight'Starlight (Astro)
'custom'Provide your own selectors (see below)

When you set framework to a supported value, Do11y automatically configures the correct CSS selectors for search bars, copy buttons, code blocks, navigation, footers, and content areas.

You can also set the framework via a meta tag:

html
<meta name="do11y-framework" content="docusaurus">

Custom selectors

Set framework: 'custom' and provide any combination of the selectors below. Any selector left null falls back to the Mintlify default.

SelectorWhat it targets
searchSelectorSearch trigger elements (input, button).
copyButtonSelector"Copy code" buttons inside code blocks.
codeBlockSelectorCode block containers (<pre>, wrappers).
navigationSelectorNavigation and sidebar regions.
footerSelectorPage footer.
contentSelectorMain content area.
tabContainerSelectorTab groups for code language/framework switching.
tocSelectorOn-page table of contents container.
feedbackSelector"Was this helpful?" feedback widget container.

Example:

js
window.Do11yConfig = {
  supabaseUrl: 'SUPABASE_PROJECT_URL',
  supabaseKey: 'SUPABASE_PUBLISHABLE_KEY',
  framework: 'custom',
  searchSelector: '#search-input',
  copyButtonSelector: '.copy-btn',
  codeBlockSelector: 'pre code',
  contentSelector: 'article.content',
  tocSelector: 'nav.toc',
  feedbackSelector: null,
};

Released under the MIT License.