Skip to main content
Themes ship their own JavaScript bundle. The starter uses Alpine.js for page behavior and a handful of custom elements for formatting that’s easier in the browser than in Twig.

The entry point

src/js/index.js
The layout loads it as a module:
This is your theme’s bundle, separate from the application’s. Nothing the app registers, such as its API client or modal controller, is available on the public site.

Alpine

Add x-data to the body in the layout so small inline components work anywhere on the page:
Then use Alpine directly in templates:
For anything larger, register a named component before Alpine starts:

The custom elements

<x-money>

Formats an amount in minor units using the browser’s locale support.

<x-credit>

Formats a credit balance, and handles the unlimited case.

<x-avatar>

Renders an image, an icon or initials.

<mode-switcher>

Wraps a button and toggles the color mode, persisting the choice.

Globals the theme sets

snippets/js.twig
window.currency gives the components a fallback currency, and your own scripts a formatting reference.

Translating strings in JavaScript

src/js/translate.js
The lookup reads a catalog exposed as window.locale, and falls back to the original string, so untranslated builds still render. Prefer translating in Twig where you can; use this only for strings created in the browser.

Writing your own element

src/js/components/countdown.js
Register it alongside the others in index.js, and always clean up timers and listeners in disconnectedCallback().

Keep it light

  • The landing page is what search engines and first-time visitors measure. Ship as little JavaScript as you can.
  • Alpine plus a few custom elements covers most marketing pages; reach for a framework only when you truly need one.
  • Load third-party embeds lazily, and put tracking in the script tag snippets rather than your bundle.