Skip to main content

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 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:

npx skills add alleyinteractive/allegro@allegro-templates

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:

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

Alpine.js

Alpine.js 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

Every template's root container is wired up with the allegroInteraction Alpine component, which gives you reactive access to the current session state and any data passed to the Interaction trigger.

PropertyTypeDescription
slugstring | nullThe slug of the Interaction that triggered this template.
sessionobject | nullReactive shortcut to $store.allegro.session — updates automatically on login or logout without a page reload.
audienceMemberobject | nullReactive shortcut to $store.allegro.audienceMember — the authenticated member's profile, or null if not logged in.
isAuthenticatedbooleanReactive shortcut to $store.allegro.isAuthenticated.
(extra data)anyAny additional data passed when the Interaction was triggered is available at the top level.

Example — personalizing content based on authentication state:

<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:

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

Web Components

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

ComponentDescription
<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 section for each component's attributes, events, and CSS variables.

Field Placeholders

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

<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:

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

Embedding Other Templates

A template can embed another template inline with the <allegro-template> element. Reference the template you want to embed by its slug with the ref attribute:

<allegro-template ref="newsletter-cta"></allegro-template>

At render time the element is replaced by the referenced template's markup. The embedded template's styles are injected into the same shadow root (once, even if you embed it multiple times), and any script it carries runs after its markup is inlined.

Passing Field Values

Any attribute other than the reserved ref and eager is passed to the embedded template as a field value, filling its {% %} placeholders by slug:

<allegro-template
ref="newsletter-cta"
headline="Subscribe today"
ctaLabel="Sign up"
></allegro-template>

Placeholders the parent does not supply are left blank.

Lazy vs. Eager Loading

By default an embedded template is lazy — it loads and expands only when it scrolls into the viewport. Add the eager attribute to expand it immediately as the parent renders:

<allegro-template ref="hero" eager></allegro-template>

Attributes

AttributeTypeDefaultDescription
reftextSlug of the template to embed. Required.
eagerbooleanfalseExpand immediately on render instead of waiting until the element scrolls into view.
(any other)textPassed to the embedded template as a field value, substituting its matching {% slug %} placeholder.
note

Embedded templates may themselves embed others, up to a depth of 10 levels. A missing or unknown ref, or a cyclic reference (a template that embeds itself, directly or indirectly), is skipped — the element is removed and a warning is logged to the console.

Display Tracking

When an Interaction offers a template, the SDK automatically records whether that template was actually seen by the visitor and emits one of two events. You don't need to wire anything up — these fire on their own.

EventWhen it fires
template_displayedThe first time any part of the rendered template scrolls into the viewport.
template_not_displayedWhen the visitor leaves the page having never seen an offered template — including when a scroll delay was never reached, so the template never rendered.

Each template offered on the page reports at most one of these events per page load. Both events carry the template's ID as object_id and identify the Interaction in the event data:

FieldDescription
object_typeAlways template.
object_idThe ID of the template that was offered.
data.interaction_slugThe slug of the Interaction that offered the template.
data.template_nameThe name of the template that was offered, or null if it has no title.
data.action_indexThe position of the template's action within the Interaction.
note

Display tracking is suppressed in preview and token-redirect flows (where delays are skipped), so previewing a template does not generate display events.

See the Event Tracking guide for how events are sent and the fields each one carries.