Customization

This page is the consumer guide for host applications that need to customize the embedded consent screen. Customization is optional.

When to enable host configuration

Use the default integration when the host only needs to display and submit consents. Add enableCustomConfig=true only when the host needs to send JSON configuration before the component renders.

URL valueCurrent behavior
absent or any value other than trueRenders immediately with default theme and UI options. SET_CONFIG messages are ignored
enableCustomConfig=trueSends CONSENTS_CONFIG_REQUIRED, waits for SET_CONFIG, sanitizes it, then renders

enableCustomConfig does not select between Legacy and Custom components. The runtime always uses the current Custom UI path.

Configuration handshake

text

Host loads iframe/WebView with ?enableCustomConfig=true
  -> mas-consents initializes the bridge
  -> mas-consents sends CONSENTS_CONFIG_REQUIRED
  -> host replies with SET_CONFIG { payload: ... }
  -> mas-consents sanitizes invalid design overrides
  -> mas-consents builds the theme and renders
  -> mas-consents fetches consents
  -> mas-consents emits CONSENTS_LOADED
  -> customer submits
  -> mas-consents emits CONSENTS_COMPLETED or CONSENTS_ERROR

If enableCustomConfig=true is present and the host never sends SET_CONFIG, the component intentionally renders nothing.

SET_CONFIG payload

The host sends configuration in the payload key of the SET_CONFIG message. These are the supported top-level keys inside payload; all of them are optional.

json

{
  "type": "SET_CONFIG",
  "payload": {
    "theme": "light",
    "design": {},
    "uiOptions": {},
    "useMockData": false,
    "consentIds": ["C01", "C02"]
  }
}

Minimal example:

json

{
  "type": "SET_CONFIG",
  "payload": {
    "theme": "light"
  }
}

Fuller example:

json

{
  "type": "SET_CONFIG",
  "payload": {
    "theme": "light",
    "consentIds": ["C01", "C02"],
    "design": {
      "color": {
        "background-button-default": "#3466F5"
      },
      "radius": {
        "radius-button": 8
      },
      "typography": {
        "headings-h4-size": "font-size-24",
        "xs": {
          "headings-h4-size": "font-size-20"
        }
      }
    },
    "uiOptions": {
      "groupDisplay": "flat",
      "collapsible": true,
      "showDescription": true
    }
  }
}

design options

Put visual overrides under the design key inside payload. These are the supported groups:

json

{
  "type": "SET_CONFIG",
  "payload": {
    "design": {
      "color": {},
      "spacing": {},
      "typography": {},
      "radius": {},
      "shadows": {},
      "border": {},
      "components": {}
    }
  }
}

Supported value semantics:

CategorySupported values in the current resolver
colorColor primitive key or valid CSS color string
spacingSpacing primitive key or number in px
typographyTypography primitive keys
radiusRadius primitive key or number in px
shadowsShadow primitive key or raw shadow string
borderStroke primitive key or number in px
componentsReserved, not consumed by the current runtime

Use semantic token keys as override names. The value can be a primitive token key or a raw value depending on the category. See Semantic tokens and Primitive tokens for the current catalog.

Important constraints:

  • border does not accept arbitrary CSS declarations like 1px solid red.
  • typography does not accept arbitrary font sizes or CSS snippets.
  • color is the most permissive category because it accepts valid CSS color values.

Responsive typography

The type model exposes xs, sm, md, lg, xl and base, but the current resolver effectively uses two groups:

  • xs for the mobile case
  • xl for every non-xs case

Recommended usage:

  • put shared values at the top level
  • add xs when mobile needs to differ
  • add xl when desktop/tablet rendering needs to differ from the top-level values
  • avoid sm, md, lg and base blocks until the resolver consumes them explicitly
json

{
  "type": "SET_CONFIG",
  "payload": {
    "design": {
      "typography": {
        "headings-h4-size": "font-size-24",
        "typography-base-family": "font-family-inter",
        "xs": {
          "headings-h4-size": "font-size-20"
        },
        "xl": {
          "headings-h4-lineheight": "line-height-2xl"
        }
      }
    }
  }
}

uiOptions

Put UI behavior overrides under the uiOptions key inside payload. This example lists the supported options:

json

{
  "type": "SET_CONFIG",
  "payload": {
    "uiOptions": {
      "collapsible": true,
      "languageSelector": true,
      "showDescription": true,
      "descriptionsAlwaysVisible": false,
      "groupDisplay": "boxed",
      "title": "Consent management",
      "description": "Review and confirm your consent preferences."
    }
  }
}

Notes:

  • showDescription defaults to true when omitted.
  • groupDisplay='boxed' changes grouping, border and container presentation.
  • title and description override the text shown by the component shell.

Validation and fallback behavior

When the host sends SET_CONFIG, the runtime sanitizes token overrides before building the theme. The current validation rules and limits are documented in Token validations.

consentIds

consentIds lets a host request a specific subset of consents.

json

{
  "type": "SET_CONFIG",
  "payload": {
    "consentIds": ["C01", "C02", "C03"]
  }
}

Behavior:

  • the host sends consentIds in SET_CONFIG
  • the frontend forwards it as consent_ids=C01,C02,C03 on the GET consents request
  • the backend decides which returned consents are editable and which are returned as read_only=true
  • read-only statements remain visible but cannot be changed by the customer

useMockData

useMockData is intended for local and STA validation only.

json

{
  "type": "SET_CONFIG",
  "payload": {
    "useMockData": true
  }
}

Behavior:

  • the runtime uses mock consent data instead of calling the backend
  • this is honored only when runtime ENV is LOCAL or STA
  • in PRO, the flag is ignored

Minimal browser host example

ts

const iframe = document.querySelector<HTMLIFrameElement>('#mas-consents')

window.addEventListener('message', (event) => {
  const msg = event.data
  if (msg?.source !== 'consents') return

  if (msg.type === 'CONSENTS_CONFIG_REQUIRED') {
    iframe?.contentWindow?.postMessage(
      {
        type: 'SET_CONFIG',
        payload: {
          theme: 'light',
          consentIds: ['C01', 'C02'],
          design: {
            color: {
              'background-button-default': '#3466F5',
            },
          },
          uiOptions: {
            groupDisplay: 'flat',
            collapsible: true,
          },
        },
      },
      '*',
    )
  }
})