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

# Experiences and Overlays

> Personalize pages and fragments with focused patches to validated base content.

An ACI experience is an overlay applied to a base page, fragment, or data document. The base stays complete and publishable. The overlay contains only what changes for an audience or experiment arm.

## Audience overlay paths

```text theme={null}
.content/overlays/audience/{audience-id}/pages/{page-id}/_index.json
.content/overlays/audience/{audience-id}/fragments/{fragment-id}/_index.json
.content/overlays/audience/{audience-id}/data/{data-path}/_index.json
```

The target document must exist in the base tree, and the audience must exist and be enabled.

## Patch a component block

Suppose `.content/pages/home/_index.json` contains this base block:

```json theme={null}
{
  "$type": "component",
  "id": "hero",
  "component": "home_hero",
  "props": {
    "eyebrow": "Agentic Content Infrastructure",
    "headline": "Build better digital experiences.",
    "description": "Validated content, delivered safely.",
    "ctaLabel": "Learn more",
    "ctaHref": "/platform/"
  }
}
```

Create `.content/overlays/audience/enterprise/pages/home/_index.json`:

```json theme={null}
{
  "$type": "page-overlay",
  "metadata": {
    "title": "Enterprise Content Infrastructure"
  },
  "regions": {
    "main": {
      "hero": {
        "props": {
          "eyebrow": "For enterprise teams",
          "headline": "Governed content operations at enterprise scale."
        }
      }
    }
  }
}
```

`hero` is the base block's `id`, not its component contract name. ACI patches that block in place and retains the base description and call to action.

<Warning>
  Keep block IDs stable and unique within a region. Renaming a base block without updating its overlays leaves those patches without a target.
</Warning>

## Merge behavior

| Overlay value                   | Result                                                    |
| ------------------------------- | --------------------------------------------------------- |
| Object                          | Deep-merges into the corresponding base object            |
| Region object keyed by block ID | Patches matching blocks in place                          |
| Region array                    | Replaces the complete region                              |
| `null`                          | Removes that field or region from the resolved experience |

Prefer narrow field patches. Replace a full region only when the personalized experience needs a different composition and you intend to own the complete replacement.

Only remove optional fields. The resolved result must still satisfy its component and layout contracts.

## Personalize a shared fragment

Fragments use the same pattern. To personalize `.content/fragments/navigation/_index.json`, create:

```text theme={null}
.content/overlays/audience/enterprise/fragments/navigation/_index.json
```

```json theme={null}
{
  "$type": "fragment-overlay",
  "props": {
    "utilityLabel": "Enterprise support",
    "utilityHref": "/enterprise/support/"
  }
}
```

Every page that references the fragment can receive the resolved audience variant without duplicating the navigation content.

## Combine locale and audience

When site configuration includes:

```json theme={null}
{
  "overlayResolution": ["locale", "audience"]
}
```

ACI can apply a locale overlay, an audience overlay, and a more specific combined overlay. A combined Spanish enterprise page uses:

```text theme={null}
.content/overlays/locale/es/audience/enterprise/pages/home/_index.json
```

The combined overlay applies after the individual dimensions and only needs to express what is different from the already resolved result.

## Validate and review

```bash theme={null}
npm run content:compile
npm run typecheck
npm run build
```

Then compare the base and selected experience on an ACI preview:

```text theme={null}
<preview-url>/
<preview-url>/?aci_audience=enterprise
```

Review the full result, including metadata, shared fragments, responsive layout, links, and fallback—not only the fields changed by the overlay.

## Troubleshooting

<AccordionGroup>
  <Accordion title="The overlay compiles but nothing changes">
    Confirm the audience is enabled, `audience` appears in `overlayResolution`, the target page ID is correct, and the region key matches the base block's `id`.
  </Accordion>

  <Accordion title="The whole region changed">
    Check whether the overlay supplies an array. Arrays replace regions; an object keyed by block ID patches selected blocks.
  </Accordion>

  <Accordion title="Removing a field fails compilation">
    A `null` value removes the field. If the component contract requires it, provide a valid replacement instead.
  </Accordion>

  <Accordion title="The locale and audience result is unexpected">
    Review the locale-only overlay, audience-only overlay, and combined overlay in that order. The combined path is most specific and applies last.
  </Accordion>
</AccordionGroup>

***

*Next: [Collection and Consent →](/aci/personalization/collection-and-consent)*
