Skip to content

Symfony UX

UX packagesCompatibilityUX packagesCompatibility
ux-autocompleteux-svelte✅ (*)
ux-chartjsux-swup
ux-cropperjsux-toggle
ux-dropzoneux-translator
ux-lazyux-turboNot yet Tested (**)
ux-live-componentux-twig
ux-notifyux-typed
ux-react✅ (*)ux-vue✅ (*)

(*) requires some modifications with imports (see below) (**) in theory there is no reason why it is not compatible, your feedback is welcome.

Prerequisites

bash
composer require symfony/stimulus-bundle

# remove the webpack-compatible @symfony/stimulus-bridge
npm rm @symfony/stimulus-bridge
composer require symfony/stimulus-bundle

# remove the webpack-compatible @symfony/stimulus-bridge
npm rm @symfony/stimulus-bridge

symfony/ux-vue

Basic installation

bash
composer require symfony/ux-vue
npm i --force
composer require symfony/ux-vue
npm i --force

After installing the Flex recipe from symfony/ux-vue you will need to correct these lines.

js
// assets/bootstrap.js
import { registerVueControllerComponents } from '@symfony/ux-vue'; 
registerVueControllerComponents(require.context('./vue/controllers', true, /\.vue$/)); 

import { startStimulusApp, registerControllers } from "vite-plugin-symfony/stimulus/helpers" 
import { registerVueControllerComponents } from "vite-plugin-symfony/stimulus/helpers/vue" 
// register Vue components before startStimulusApp
registerVueControllerComponents(import.meta.glob('./vue/controllers/**/*.vue')) 

const app = startStimulusApp();
registerControllers(app, import.meta.glob('./controllers/*_(lazy)\?controller.[jt]s(x)\?'))
// assets/bootstrap.js
import { registerVueControllerComponents } from '@symfony/ux-vue'; 
registerVueControllerComponents(require.context('./vue/controllers', true, /\.vue$/)); 

import { startStimulusApp, registerControllers } from "vite-plugin-symfony/stimulus/helpers" 
import { registerVueControllerComponents } from "vite-plugin-symfony/stimulus/helpers/vue" 
// register Vue components before startStimulusApp
registerVueControllerComponents(import.meta.glob('./vue/controllers/**/*.vue')) 

const app = startStimulusApp();
registerControllers(app, import.meta.glob('./controllers/*_(lazy)\?controller.[jt]s(x)\?'))
js
// vite.config.js
import { defineConfig } from 'vite'

import symfonyPlugin from 'vite-plugin-symfony';
import vuePlugin from "@vitejs/plugin-vue";

export default defineConfig({
  plugins: [
    vuePlugin(), 
    symfonyPlugin({
      stimulus: true 
    }),
  ],
  build: {
    rollupOptions: {
      input: {
        "app": "./assets/app.js",
      }
    },
  },
});
// vite.config.js
import { defineConfig } from 'vite'

import symfonyPlugin from 'vite-plugin-symfony';
import vuePlugin from "@vitejs/plugin-vue";

export default defineConfig({
  plugins: [
    vuePlugin(), 
    symfonyPlugin({
      stimulus: true 
    }),
  ],
  build: {
    rollupOptions: {
      input: {
        "app": "./assets/app.js",
      }
    },
  },
});
twig
{# your-template.html.twig #}
<div {{ vue_component('Hello', { 'name': 'Vite & Stimulus' }) }}></div>
{# your-template.html.twig #}
<div {{ vue_component('Hello', { 'name': 'Vite & Stimulus' }) }}></div>
vue
<!-- assets/vue/controllers/Hello.vue -->
<template>
    <div>Hello {{ name }}!</div>
</template>

<script setup>
    defineProps({
        name: String
    });
</script>
<!-- assets/vue/controllers/Hello.vue -->
<template>
    <div>Hello {{ name }}!</div>
</template>

<script setup>
    defineProps({
        name: String
    });
</script>

Documentation : Symfony doc, Symfony UX.

symfony/ux-react

Basic installation

bash
composer require symfony/ux-react
npm i --force
composer require symfony/ux-react
npm i --force

After installing the Flex recipe from symfony/ux-react you will need to correct these lines.

js
// assets/bootstrap.js
import { registerReactControllerComponents } from '@symfony/ux-react'; 
registerReactControllerComponents(require.context('./react/controllers', true, /\.(j|t)sx?$/)); 

import { startStimulusApp, registerControllers } from "vite-plugin-symfony/stimulus/helpers" 
import { registerReactControllerComponents } from "vite-plugin-symfony/stimulus/helpers/react" 
registerReactControllerComponents(import.meta.glob('./react/controllers/**/*.[jt]s(x)\?')); 

const app = startStimulusApp();
registerControllers(app, import.meta.glob('./controllers/*_(lazy)\?controller.[jt]s(x)\?'))
// assets/bootstrap.js
import { registerReactControllerComponents } from '@symfony/ux-react'; 
registerReactControllerComponents(require.context('./react/controllers', true, /\.(j|t)sx?$/)); 

import { startStimulusApp, registerControllers } from "vite-plugin-symfony/stimulus/helpers" 
import { registerReactControllerComponents } from "vite-plugin-symfony/stimulus/helpers/react" 
registerReactControllerComponents(import.meta.glob('./react/controllers/**/*.[jt]s(x)\?')); 

const app = startStimulusApp();
registerControllers(app, import.meta.glob('./controllers/*_(lazy)\?controller.[jt]s(x)\?'))

Because import.meta.glob create already lazy imports, you need to set fetch eager (otherwise your component will become really too lazy).

json
{
    "controllers": {
        "@symfony/ux-react": {
            "react": {
                "enabled": true,
                "fetch": "eager" 
            }
        },

    },
    "entrypoints": []
}
{
    "controllers": {
        "@symfony/ux-react": {
            "react": {
                "enabled": true,
                "fetch": "eager" 
            }
        },

    },
    "entrypoints": []
}
js
// vite.config.js
import { defineConfig } from 'vite'

import symfonyPlugin from 'vite-plugin-symfony';
import reactPlugin from '@vitejs/plugin-react';

export default defineConfig({
  plugins: [
    reactPlugin(), 
    symfonyPlugin({
      stimulus: true 
    }),
  ],
  build: {
    rollupOptions: {
      input: {
        "app": "./assets/app.js",
      }
    },
  },
});
// vite.config.js
import { defineConfig } from 'vite'

import symfonyPlugin from 'vite-plugin-symfony';
import reactPlugin from '@vitejs/plugin-react';

export default defineConfig({
  plugins: [
    reactPlugin(), 
    symfonyPlugin({
      stimulus: true 
    }),
  ],
  build: {
    rollupOptions: {
      input: {
        "app": "./assets/app.js",
      }
    },
  },
});
twig
{# base.html.twig #}
{{ vite_entry_link_tags('app') }}
{{ vite_entry_script_tags('app', {
    dependency: 'react' 
  }) }}
{# base.html.twig #}
{{ vite_entry_link_tags('app') }}
{{ vite_entry_script_tags('app', {
    dependency: 'react' 
  }) }}
twig
{# your-template.html.twig #}
<div {{ react_component('Hello', { 'fullName': 'Vite & Stimulus' }) }}></div>
{# your-template.html.twig #}
<div {{ react_component('Hello', { 'fullName': 'Vite & Stimulus' }) }}></div>
jsx
// assets/react/controllers/Hello.jsx
import React from 'react';

export default function (props) {
    return <div>Hello {props.fullName}</div>;
}
// assets/react/controllers/Hello.jsx
import React from 'react';

export default function (props) {
    return <div>Hello {props.fullName}</div>;
}

Documentation : Symfony doc, Symfony UX React.

symfony/ux-svelte

Basic installation

bash
composer require symfony/ux-svelte
npm i --force
composer require symfony/ux-svelte
npm i --force

After installing the Flex recipe from symfony/ux-svelte you will need to correct these lines.

js
// assets/bootstrap.js
import { registerSvelteControllerComponents } from '@symfony/ux-svelte'; 
registerSvelteControllerComponents(require.context('./svelte/controllers', true, /\.svelte$/)); 

import { startStimulusApp, registerControllers } from "vite-plugin-symfony/stimulus/helpers" 
import { registerSvelteControllerComponents } from "vite-plugin-symfony/stimulus/helpers/svelte" 
registerSvelteControllerComponents(import.meta.glob('./svelte/controllers/**/*.svelte')); 

const app = startStimulusApp();
registerControllers(app, import.meta.glob('./controllers/*_(lazy)\?controller.[jt]s(x)\?'))
// assets/bootstrap.js
import { registerSvelteControllerComponents } from '@symfony/ux-svelte'; 
registerSvelteControllerComponents(require.context('./svelte/controllers', true, /\.svelte$/)); 

import { startStimulusApp, registerControllers } from "vite-plugin-symfony/stimulus/helpers" 
import { registerSvelteControllerComponents } from "vite-plugin-symfony/stimulus/helpers/svelte" 
registerSvelteControllerComponents(import.meta.glob('./svelte/controllers/**/*.svelte')); 

const app = startStimulusApp();
registerControllers(app, import.meta.glob('./controllers/*_(lazy)\?controller.[jt]s(x)\?'))

Because import.meta.glob create already lazy imports, you need to set fetch eager (otherwise your component will become really too lazy).

json
{
    "controllers": {
        "@symfony/ux-svelte": {
            "svelte": {
                "enabled": true,
                "fetch": "eager" 
            }
        },

    },
    "entrypoints": []
}
{
    "controllers": {
        "@symfony/ux-svelte": {
            "svelte": {
                "enabled": true,
                "fetch": "eager" 
            }
        },

    },
    "entrypoints": []
}
js
// vite.config.js
import { defineConfig } from 'vite'

import symfonyPlugin from 'vite-plugin-symfony';
import { svelte } from '@sveltejs/vite-plugin-svelte'

export default defineConfig({
  plugins: [
    svelte(), 
    symfonyPlugin({
      stimulus: true
    }),
  ],
  build: {
    rollupOptions: {
      input: {
        "app": "./assets/app.js",
      }
    },
  },
});
// vite.config.js
import { defineConfig } from 'vite'

import symfonyPlugin from 'vite-plugin-symfony';
import { svelte } from '@sveltejs/vite-plugin-svelte'

export default defineConfig({
  plugins: [
    svelte(), 
    symfonyPlugin({
      stimulus: true
    }),
  ],
  build: {
    rollupOptions: {
      input: {
        "app": "./assets/app.js",
      }
    },
  },
});
js
// svelte.config.js
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'

export default {
  // Consult https://svelte.dev/docs#compile-time-svelte-preprocess
  // for more information about preprocessors
  preprocess: vitePreprocess(),
}
// svelte.config.js
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'

export default {
  // Consult https://svelte.dev/docs#compile-time-svelte-preprocess
  // for more information about preprocessors
  preprocess: vitePreprocess(),
}
twig
{# your-template.html.twig #}
<div {{ svelte_component('Hello', { 'name': 'Vite & Stimulus' }) }}></div>
{# your-template.html.twig #}
<div {{ svelte_component('Hello', { 'name': 'Vite & Stimulus' }) }}></div>
svelte
<!-- assets/svelte/controllers/Hello.svelte -->
<script>
    export let name = "Svelte";
</script>

<div>Hello {name}</div>
<!-- assets/svelte/controllers/Hello.svelte -->
<script>
    export let name = "Svelte";
</script>

<div>Hello {name}</div>

Documentation : Symfony doc, Symfony UX Svelte.

Released under the MIT License.