> ## 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.

# Personalization Quickstart

> Run the ACI starter, understand its behavior-based audience, and prepare a personalized experience for preview.

This guide gives you a working personalization path: a visitor records a preference, ACI evaluates that consented event, and a later request can receive the matching compiled experience. Visitors without a matching membership continue to receive the base page.

<Info>
  Access: Must be enabled for your organization. Contact your Gradial team to get access.
</Info>

## Prerequisites

* Node.js 22 or newer
* npm 10 or newer
* A personalization-enabled ACI site for hosted preview

Local development does not require an ACI account. It verifies content, contracts, overlays, and rendering. Hosted preview is required to verify consented identity and request-time selection.

## 1. Create the starter site

Astro is the shortest path to a new ACI project:

```bash theme={null}
npx @gradial/aci init my-site \
  --template astro-starter \
  --with-starter-content

cd my-site
npm install
npm run dev
```

Open the local URL printed by Astro. The starter compiles `.content/` on startup and refreshes the page when content changes.

## 2. Find the personalization resources

The starter includes one complete example:

```text theme={null}
.content/
├── audiences/
│   └── preference-blue/_index.json
├── segments/
│   └── preference-blue/_index.json
├── overlays/
│   └── audience/preference-blue/pages/home/_index.json
├── pages/home/_index.json
└── config/site.json
```

The base homepage contains a component block with a stable ID:

```json theme={null}
{
  "$type": "component",
  "id": "personalization-choice",
  "component": "personalization_choice",
  "props": {
    "title": "Choose your connection preference",
    "description": "Select a preference, allow the update to process, then refresh personalization.",
    "redLabel": "Choose Red",
    "blueLabel": "Choose Blue",
    "refreshLabel": "Refresh personalization"
  }
}
```

The rendered buttons record a custom event without application-specific analytics code:

```html theme={null}
<button
  data-aci-event="preference"
  data-aci-prop-color="blue">
  Choose Blue
</button>
```

ACI normalizes that event to `custom.preference`.

## 3. Understand the segment

`.content/segments/preference-blue/_index.json` defines the behavior that qualifies:

```json theme={null}
{
  "$type": "segment",
  "props": {
    "id": "preference-blue",
    "displayName": "Latest preference is Blue",
    "status": "enabled",
    "priority": 100,
    "criteria": {
      "all": [
        {
          "type": "event_latest",
          "event": "custom.preference",
          "properties": {
            "color": "blue"
          }
        }
      ]
    }
  }
}
```

`event_latest` evaluates the most recent event with that name. Here, the `color` property must be `blue`.

## 4. Connect the segment to an audience

`.content/audiences/preference-blue/_index.json` gives that membership a stable target:

```json theme={null}
{
  "$type": "audience",
  "props": {
    "id": "preference-blue",
    "displayName": "Blue preference",
    "status": "enabled",
    "priority": 100,
    "membershipSource": "segment",
    "segmentRef": "$ref:segments/preference-blue"
  }
}
```

The segment decides membership. The audience decides which experience can be selected. Keeping them separate lets you reuse targeting logic across content.

## 5. Inspect the experience overlay

`.content/overlays/audience/preference-blue/pages/home/_index.json` patches the base block by its ID:

```json theme={null}
{
  "$type": "page-overlay",
  "regions": {
    "main": {
      "personalization-choice": {
        "props": {
          "title": "Blue preference active",
          "description": "Your latest preference is Blue. Choose Red to replace it."
        }
      }
    }
  }
}
```

Only the two changed fields appear in the overlay. ACI retains the remaining props from the base component and validates the resolved experience against the same contract.

## 6. Confirm site configuration

The starter's `.content/config/site.json` includes the audience dimension and enables collection:

```json theme={null}
{
  "overlayResolution": ["locale", "audience"],
  "personalization": {
    "collect": true,
    "consentPreset": "c15t",
    "consentCategories": "measurement,marketing"
  }
}
```

The preset connects to an existing consent manager; it does not define your privacy policy. See [Collection and Consent](/aci/personalization/collection-and-consent) before using real traffic.

## 7. Run the local gates

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

A successful compile proves that the segment, audience reference, overlay, base page, and component contract resolve together. A successful local render does not prove hosted identity or edge selection.

## 8. Preview the selected experience

Push the reviewed content to an ACI branch, then open the branch preview supplied for your site:

```bash theme={null}
npm exec -- aci branch create personalization-preference \
  --source-ref main

npm exec -- aci content push \
  --branch personalization-preference \
  --dry-run

npm exec -- aci content push \
  --branch personalization-preference
```

On the ACI preview surface, compare:

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

The first request must show the base experience. The second explicitly selects the compiled audience variant for preview. The `aci_audience` selector is a preview control; production selection follows authored targeting and consented membership.

When both paths are correct, continue with [Preview, Publish, and Roll Back](/aci/personalization/preview-publish-and-rollback).

***

*Next: [Audiences and Segments →](/aci/personalization/audiences-and-segments)*
