# Templates

This guide covers the technical details of how Allegro templates are rendered on the page. For an overview of creating and managing templates, see [Templates](/product/interactions/templates.md) in the product docs.

Claude skill available

If you use Claude Code, install the `allegro-templates` skill for in-editor guidance on file structure, Alpine.js patterns, field placeholders, and local preview:

```sh
npx skills add alleyinteractive/allegro@allegro-templates

```

## Rendering Model[​](#rendering-model "Direct link to Rendering Model")

When an Interaction triggers, Allegro creates a host `<div>` and attaches an **open shadow root** to it. All of the template's markup, styles, and external stylesheets are injected inside that shadow root before the host is placed in the DOM at the configured target position.

The shadow DOM provides full CSS isolation — styles defined in the template don't leak out to the host page, and the host page's styles don't bleed in.

The host element carries a `data-allegro-interaction` attribute set to the Interaction's slug, which you can use for external targeting if needed:

```css
/* from the host page — selects the template host element */
[data-allegro-interaction='my-interaction'] {
    margin-top: 2rem;
}

```

## Alpine.js[​](#alpinejs "Direct link to Alpine.js")

[Alpine.js](https://alpinejs.dev) v3 is loaded automatically from CDN the first time a template renders — no `<script>` tag required. If Alpine is already present on the page, Allegro uses it directly.

Alpine is initialized on the shadow root, so directives in your template HTML work as expected.

### `x-data` Scope[​](#x-data-scope "Direct link to x-data-scope")

Every template's root container is wired up with the `allegroInteraction` [Alpine component](/developer/guides/alpine-state.md), which gives you reactive access to the current session state and any data passed to the Interaction trigger.

| Property          | Type             | Description                                                                                                            |
| ----------------- | ---------------- | ---------------------------------------------------------------------------------------------------------------------- |
| `slug`            | `string \| null` | The slug of the Interaction that triggered this template.                                                              |
| `session`         | `object \| null` | Reactive shortcut to `$store.allegro.session` — updates automatically on login or logout without a page reload.        |
| `audienceMember`  | `object \| null` | Reactive shortcut to `$store.allegro.audienceMember` — the authenticated member's profile, or `null` if not logged in. |
| `isAuthenticated` | `boolean`        | Reactive shortcut to `$store.allegro.isAuthenticated`.                                                                 |
| *(extra data)*    | any              | Any additional data passed when the Interaction was triggered is available at the top level.                           |

Example — personalizing content based on authentication state:

```html
<div x-show="isAuthenticated">
    Welcome back, <span x-text="audienceMember.name"></span>!
</div>

<div x-show="!isAuthenticated">
    <p>Sign in to continue reading.</p>
    <allegro-login-form></allegro-login-form>
</div>

```

Example — reading extra data passed by the Interaction trigger:

```html
<!-- if the interaction was triggered with { articleId: '123' } -->
<p x-text="`Reading article ${articleId}`"></p>

```

The session state is reactive — if the member logs in after the template is already on the page, Alpine re-renders any bound expressions automatically. See [Alpine State Reference](/developer/guides/alpine-state.md) for the full store shape, the reactivity model, and more recipes.

For the full list of Alpine directives and features, see the [Alpine.js documentation](https://alpinejs.dev/start-here).

## Web Components[​](#web-components "Direct link to Web Components")

Allegro's built-in web components are registered on the page by the SDK and are available inside templates:

| Component                | Description                                     |
| ------------------------ | ----------------------------------------------- |
| `<allegro-login-form>`   | Login form with email/password and social login |
| `<allegro-email-form>`   | Email capture form                              |
| `<allegro-content-gate>` | Paywall / content gate                          |

See the [Components](/developer/components/login-form.md) section for each component's attributes, events, and CSS variables.

## Field Placeholders[​](#field-placeholders "Direct link to Field Placeholders")

Field values defined on the Interaction are substituted into the template HTML before rendering. Reference a field by its slug wrapped in `{% %}`:

```html
<h2>{% headline %}</h2>
<p>{% bodyText %}</p>
<a href="{% ctaUrl %}">{% ctaLabel %}</a>

```

Substitution runs before Alpine.js initializes, so field values are baked into the HTML and can be used inside Alpine expressions:

```html
<div x-data="{ open: false }">
    <button @click="open = !open">{% toggleLabel %}</button>
    <p x-show="open">{% bodyText %}</p>
</div>

```
