redant/twig-components-bundle
redant/twig-components-bundle brings component-based UI development to Symfony Twig templates: define reusable components with props and slots, compose views cleanly, and keep markup modular and maintainable without adding a frontend framework. Ideal for design systems and shared template libraries.
composer require redant/twig-components-bundle. With Symfony Flex the bundle is usually auto-registered in config/bundles.php; if not, add Redant\TwigComponentsBundle\RedantTwigComponentsBundle::class => ['all' => true].vendor/redant/twig-components-bundle/README.md, then src/ — specifically the Twig extension (the Twig function/tag it exposes), the component base class or interface, and the compiler pass that registers components. Confirm exact class names and the service tag; do not assume they match Symfony UX naming.DependencyInjection/Configuration.php to see which paths, template roots, and naming conventions are configurable, then create config/packages/redant_twig_components.yaml with only the keys you need.src/Twig/Component/) and its template (typically under templates/components/), render it once from an existing page template, and verify output in the Twig profiler panel before building more.component('alert', { type: 'warning', message: '...' })). Copy the exact signature from the extension class — a wrong function name or argument shape is the most common first-hour failure.Class + template pairs. One PHP class per component holds the props (public properties or constructor arguments with defaults) and any derived data; one Twig template renders it. Keep the template dumb: no queries, no business logic, just markup and conditionals on the props.
Props with defaults. Give every prop a sensible default so the component is usable with zero arguments, and let callers override only what they need. Validate or normalise props in a setter or a getContext()-style method rather than in Twig.
Variant mapping in PHP, not Twig. Map semantic props to CSS classes in the component class (type: 'warning' → ['bg' => 'bg-yellow-100', ...]) and pass the resulting classes as context. This keeps Tailwind/Bootstrap strings out of templates and makes variants testable.
Slots and child content. For components that wrap markup, capture inner content via a block or a content variable and pass it through. Decide deliberately whether it is escaped or trusted, and document that decision on the component.
Composition. Let a Card component render Badge and Button components inside its template. Keep composition shallow (two or three levels); deep nesting makes the Twig profiler unreadable and prop plumbing painful.
Registration and autowiring. Most bundles of this shape rely on autoconfigure: true plus a service tag applied to classes implementing the component interface. Verify the tag with bin/console debug:container --tag=<tag> and make sure your services.yaml App\ resource block covers the component directory.
Forms. When wrapping form widgets, pass the FormView object into the component and render with form_label/form_widget inside the component template — do not flatten the form view into scalar props.
Testing. Unit-test the class's context-building method directly (no Twig needed) and add one Twig integration test per component that renders it with representative props and asserts on the HTML.
PHP-side rendering. If the bundle exposes a renderer service, inject it into controllers or mail builders to render components outside Twig — useful for emails and API-adjacent HTML fragments.
autoconfigure is off or the component directory is excluded from the App\ resource. Fix the tag, not the template.twig.default_path. A component class that resolves but renders an empty string is almost always a path/naming mismatch — check the Twig profiler's template name, not just the output.{{ component(...) }} under Twig's default autoescaping will print tags as text unless the extension marks the result safe or you apply |raw. Check how the extension declares its output; apply |raw at the render site only, never inside the component template.component() Twig function or a similar tag, it will conflict with symfony/ux-twig-component. Do not install both; if you are evaluating, prefer the actively maintained UX package unless this bundle's API specifically fits your codebase.bin/console cache:clear after adding either; in dev, confirm twig.cache is off.debug:twig won't list components. Use debug:container --tag=<tag> for registration and the Twig profiler panel for render-time context.templates/bundles/RedantTwigComponentsBundle/... rather than editing vendor/.How can I help you explore Laravel packages today?