SyliusCon 2025
Early Bird Deal
LogoLogo
🛣️ Roadmap💻 Sylius Demo💬 Community Slack
  • Sylius Documentation
  • Sylius Plugins
  • Sylius Stack
  • 📖Sylius Documentation
  • Organization
    • Sylius Team
  • Release Cycle
    • Backwards Compatibility Promise
  • Getting Started with Sylius
    • Installation
    • Basic Configuration
    • Shipping & Payment
    • First Product
    • Customizing the Shop
    • Customizing Business Logic
    • Using API
    • Installing Plugins
    • Deployment
    • Summary
  • The Book
    • Introduction to Sylius
    • Installation
      • System Requirements
      • Sylius CE Installation
        • Sylius CE Installation with Docker
      • ➕Sylius Plus Installation
      • Upgrading Sylius CE
      • Upgrading Sylius Plus
    • Architecture
      • Architecture Overview
      • Architectural Drivers
      • Resource Layer
      • State Machine
      • Translations
      • E-Mails
      • Contact
      • Fixtures
      • Events
    • Configuration
      • Channels
      • Locales
      • Currencies
    • Customers
      • Customer & ShopUser
      • ➕Customer Pools
      • AdminUser
      • Addresses
        • Countries
        • Zones
        • Addresses
        • Address Book
    • Products
      • Products
      • Product Reviews
      • Product Associations
      • Attributes
      • Pricing
      • Catalog Promotions
      • Taxons
      • Inventory
      • ➕Multi-Source Inventory
      • Search
    • Carts & Orders
      • Orders
      • Cart flow
      • Taxation
      • Adjustments
      • Cart Promotions
      • Coupons
      • Payments
      • 🧩Invoices
      • Shipments
    • 🎨Frontend & Themes
    • Support
    • Contributing
      • Contributing Code
        • Submitting a Patch
        • ⚠️Security Issues
        • Coding Standards
        • Conventions
        • Sylius License and Trademark
      • Contributing Translations
      • Key Contributors
  • The Customization Guide
    • Customizing Models
      • How to add a custom model?
      • How to add a custom translatable model?
    • Customizing Forms
      • How to add a live form for a custom model?
    • Customizing Templates
    • Customizing Styles
    • Customizing Dynamic Elements
    • Customizing Validation
    • Customizing Menus
    • Customizing Translations
    • Customizing Flashes
    • Customizing State Machines
    • Customizing Grids
    • Customizing Fixtures
    • Customizing API
    • Customizing Serialization of API
    • Customizing Payments
      • How to integrate a Payment Gateway as a Plugin?
  • 🧑‍🍳The Cookbook
  • How to resize images?
  • How to add one image to an entity?
  • How to add multiple images to an entity?
  • How to add a custom cart promotion action?
  • How to add a custom cart promotion rule?
  • Sylius 1.X Documentation
    • 📓Sylius 1.x Documentation
Powered by GitBook
LogoLogo

Developer

  • Community
  • Online Course

About

  • Team

© 2025 Sylius. All Rights Reserved

On this page
  • Prerequisites
  • Example Use Cases
  • 📁 Default Directory Structure
  • Adding a Stimulus Controller Using Automatic Discovery
  • 🔧 Steps
  • Disabling or Enabling Existing Stimulus Controllers
  • Example: Disable the taxon-tree Controller in the Admin Panel
  • 🗂 Common Keys
  • 3: Manual Registration
  • Steps
  • ⚠️ Compatibility Note
  • 🐞 Troubleshooting Tips
  • Learn More

Was this helpful?

Edit on GitHub
  1. The Customization Guide

Customizing Dynamic Elements

Sylius 2.1 adopts a modern JavaScript architecture based on Symfony UX and StimulusJS. This setup enables you to build dynamic, interactive frontend behavior while following clean Symfony conventions.

This guide explains how to customize and register JavaScript controllers in your Sylius frontend. It covers automatic controller discovery, manual registration, and JSON-based configuration. You’ll also find real-world examples and tips for debugging common issues.


Prerequisites

  • Sylius 2.1 or later

  • Webpack Encore is properly configured

  • Basic knowledge of StimulusJS


Example Use Cases

You might want to customize dynamic elements in cases like:

  • Adding quantity increment buttons to the product page using a custom Stimulus controller

  • Creating a sticky "Add to Cart" bar that reacts to scroll events

  • Updating shipping method options dynamically based on the selected country during checkout

  • Enhancing admin panel UX with collapsible panels or sortable table rows

Each of these examples relies on connecting a Stimulus controller to a DOM element, configuring it through data-* attributes, and optionally extending or overriding the default Sylius behavior.


📁 Default Directory Structure

By default, Sylius expects Stimulus controllers to reside in the assets/controllers/ directory. Each controller should be named following the pattern *_controller.js.

assets/
├── admin/
│   └── controllers.json
├── shop/
│   └── controllers.json
├── controllers/          ← Auto-discovered controllers
│   └── alert_controller.js
└── controllers.json      ← Shared config imported by Flex

Adding a Stimulus Controller Using Automatic Discovery

This is the simplest way to register a new Stimulus controller. If your controller is located in the expected directory and follows the naming conventions, Symfony UX will automatically detect and load it—no manual configuration needed.

🔧 Steps

1. Create the Stimulus Controller

Place your file under assets/admin/controllers/ and name it using the *_controller.js pattern.

// assets/admin/controllers/alert_controller.js

import { Controller } from '@hotwired/stimulus';

export default class extends Controller {
  connect() {
    alert(this.element.dataset.message || 'Test Alert!');
  }
}

This controller will automatically be registered as alert.

2. Create a Twig Template

Use the stimulus_controller() Twig helper to bind your controller to a DOM element.

{# templates/admin/order/show/alert.html.twig #}

<div {{ stimulus_controller('alert') }}></div>

Optional: pass data-* attributes using stimulus_controller() options if needed.

3. Register the Template via a Twig Hook

Hook your controller’s template into the desired part of the admin UI using the Sylius Twig hook system.

# config/packages/_sylius.yaml

sylius_twig_hooks:
    hooks:
        'sylius_admin.order.show.content':
            alert:
                template: 'admin/order/show/alert.html.twig'

This ensures your controller is rendered at the sylius_admin.order.show.content hook point, without overriding core templates.

Result

  • Your controller is discovered automatically.

  • It's attached to the DOM using stimulus_controller().

  • It’s injected upgrade-safely using a Twig hook.


Disabling or Enabling Existing Stimulus Controllers

In some situations, you may want to disable a built-in controller (e.g., to replace it with your own) or change how it's loaded (e.g., only when needed). This is possible via the controllers.json file using Symfony UX's controller configuration.

Example: Disable the taxon-tree Controller in the Admin Panel

To prevent the built-in taxon-tree Stimulus controller from loading:

📁 File: assets/admin/controllers.json

// assets/admin/controllers.json

{
  "controllers": {
    "@sylius/admin-bundle": {
      "taxon-tree": {
        "enabled": false,
        "fetch": "lazy"
      }
    }
  }
}

This disables the controller entirely (enabled: false), and even if enabled, it would only load lazily.

🗂 Common Keys

  • enabled: true or false

    • Controls whether the controller is loaded at all.

  • fetch: "lazy" (default) or "eager"

    • Defines when the controller is fetched:

      • lazy: loaded only when used in the DOM

      • eager: loaded immediately on page load

💡 Pro Tip

You can override or replace a disabled controller by registering your own under the same name, or by targeting the same HTML with a new controller.


3: Manual Registration

Use manual registration when:

  • Your controller is located outside the default controllers/ directory

  • You're integrating a controller from a third-party or custom plugin

  • You need more explicit control over how and when the controller is loaded

Steps

1. Create Your Stimulus Controller

// assets/shop/custom/confirm_controller.js

import { Controller } from '@hotwired/stimulus';

export default class extends Controller {
  connect() {
    console.log('Confirm controller loaded.');
  }

  onClick(event) {
    event.preventDefault();
    console.log('Button clicked!');
  }
}

This controller defines a connect() lifecycle method and an onClick() action for buttons.

2. Register the Controller Manually

// assets/shop/bootstrap.js

import { Application } from '@hotwired/stimulus';
import ConfirmController from './custom/confirm_controller';

const app = Application.start();
app.register('confirm', ConfirmController);

This ensures that Stimulus knows about your confirm controller and connects it when used in templates.

3. Create the Twig Template

{# templates/shop/order/confirmation.html.twig #}

<button
    class="btn btn-primary"
    data-action="click->confirm#onClick"
    {{ stimulus_controller('confirm') }}>
    Confirm
</button>

This adds a button that triggers your onClick action when clicked.

4. Register the Template via Twig Hooks

Use the Sylius Twig hooks system to inject your custom button into the Thank You page (order confirmation).

# config/packages/_sylius.yaml

sylius_twig_hooks:
    hooks:
        'sylius_shop.order.thank_you.content.buttons#customer': # for logged in customer
            confirmation:
                template: 'shop/order/confirmation.html.twig'

        'sylius_shop.order.thank_you.content.buttons#guest': # for guest
            confirmation:
                template: 'shop/order/confirmation.html.twig'

This hook ensures that your controller-powered button is shown after order placement, regardless of user type.


⚠️ Compatibility Note


🐞 Troubleshooting Tips

  • Controller Not Executing? Ensure Webpack Encore has rebuilt your assets (yarn dev or yarn build).

  • Incorrect Controller Name? Verify that the data-controller attribute matches the registered controller name.

  • Console Errors? Use browser developer tools to check if your controller is compiled and loaded correctly.

  • Caching Issues? Clear both Symfony and browser caches to ensure the latest assets are loaded.

Learn More

PreviousCustomizing StylesNextCustomizing Validation

Last updated 2 days ago

Was this helpful?

If your application is based on Sylius/Standard prior to the 2.1 release, you must first upgrade your project as outlined . Without this upgrade, your app will rely on the legacy assets system, and this guide will not apply.

here
Stimulus documentation
Example Plugin Using New Assets Mechanism
✅ Result: The alert will be shown every time you enter the order show page!
✅ Result: Taxon tree is no longer visible.
✅ Result: A new button appears that logs to the console every time it is clicked!