Drupal Integration
apps/docs/src/content/docs/framework-integration/drupal Click to copy apps/docs/src/content/docs/framework-integration/drupal Drupal Integration
Section titled “Drupal Integration”HELIX is purpose-built for Drupal. The full integration guide lives in the Drupal Integration section. This page is a quick-start summary covering the essential patterns.
Installation
Section titled “Installation”Two options are available:
Via npm (recommended for custom themes)
Section titled “Via npm (recommended for custom themes)”npm install @helixui/libraryReference the built files from your theme’s .libraries.yml.
Via CDN
Section titled “Via CDN”helix: js: https://cdn.jsdelivr.net/npm/@helixui/library/dist/index.js: { type: external, attributes: { type: module } }See CDN Installation for the full setup.
Using Components in Twig
Section titled “Using Components in Twig”HELIX elements are standard HTML — use them directly in .html.twig templates:
{# templates/block--my-block.html.twig #}
<hx-button variant="primary" type="button"> {{ 'Save changes'|t }}</hx-button>Passing Dynamic Values
Section titled “Passing Dynamic Values”Use Twig variable interpolation to set attributes:
<hx-button variant="{{ button_variant|default('primary') }}" {% if disabled %}disabled{% endif %}> {{ label }}</hx-button>The hx-size Attribute Convention
Section titled “The hx-size Attribute Convention”Several HELIX components use hx-size instead of the native size attribute for
setting dimensions (e.g., sm, md, lg). The prefix avoids collisions with the
native HTML size attribute (which has numeric semantics on <input> and <select>).
It does share the hx-* namespace with htmx but does not collide with any current
htmx attribute name.
Components that use hx-size: hx-button, hx-icon-button, hx-spinner,
hx-avatar, hx-badge, and others.
{# Correct — use hx-size, not size #}<hx-button variant="primary" hx-size="lg">Submit</hx-button>
{# Wrong — size is NOT the same as hx-size #}<hx-button variant="primary" size="lg">Submit</hx-button>Boolean Attributes in Twig
Section titled “Boolean Attributes in Twig”Follow HELIX’s boolean attribute semantics. Output the attribute name without a value when true; omit it entirely when false:
{# Correct #}<hx-button {% if is_disabled %}disabled{% endif %}> {{ label }}</hx-button>
{# Wrong — disabled="false" still disables #}<hx-button disabled="{{ is_disabled ? 'true' : 'false' }}"> {{ label }}</hx-button>Using Slots
Section titled “Using Slots”Twig child content maps to the default slot:
<hx-card> <span slot="heading">{{ card_title }}</span> <div>{{ card_body }}</div></hx-card>See Slots in Twig for named slot patterns.
Drupal Behaviors for Event Handling
Section titled “Drupal Behaviors for Event Handling”Drupal Behaviors are the correct place to attach JavaScript event listeners to HELIX components. They re-fire on AJAX updates.
(function (Drupal) { Drupal.behaviors.myFeature = { attach(context) { const buttons = context.querySelectorAll('hx-button[data-my-action]');
buttons.forEach((btn) => { if (btn.dataset.behaviorAttached) return; // prevent double-attach btn.dataset.behaviorAttached = 'true';
btn.addEventListener('hx-click', (event) => { Drupal.ajax({ url: btn.dataset.url }).execute(); }); }); }, };})(Drupal);See Drupal Behaviors — With Web Components for detailed patterns.
Form API Integration
Section titled “Form API Integration”HELIX form components participate in native HTML forms. In Drupal, combine with the Form API’s #attributes key:
$form['email'] = [ '#type' => 'html_tag', '#tag' => 'hx-text-input', '#attributes' => [ 'name' => 'email', 'type' => 'email', 'required' => TRUE, 'placeholder' => $this->t('Enter your email'), ],];For full Drupal Form API element plugins, see Form API Integration.
Per-Component Loading
Section titled “Per-Component Loading”For performance, load only the components used on each page:
helix-button: js: /libraries/helixui/dist/components/hx-button/index.js: { attributes: { type: module }, minified: true }
helix-text-input: js: /libraries/helixui/dist/components/hx-text-input/index.js: { attributes: { type: module }, minified: true }Adjust the /libraries/helixui/... prefix to match where you mount @helixui/library in your Drupal site. The canonical generated library file ships in the @helixui/drupal-starter package (helixui.libraries.yml, auto-generated by pnpm run generate:drupal-libraries) — use it as the source of truth for path conventions.
See Per-Component Loading for the full strategy.
Full Documentation
Section titled “Full Documentation”This page covers the basics. The complete Drupal integration guide includes:
- Installation (npm, CDN, Drupal Module)
- Twig Templates — Fundamentals
- Twig — Properties & Attributes
- Drupal Behaviors
- Library System
- Forms — Form API
- Performance & Lazy Loading
- Troubleshooting