Symfony’s global form themes apply everywhere. When admin and customer-facing areas use different markup, select the appropriate theme for each form in the template that owns that form.
Last updated: October 17, 2026.
{# templates/account/profile.html.twig #}
{% extends 'account/base.html.twig' %}
{% form_theme profileForm 'account/form_theme.html.twig' %}
{% block body %}
{{ form_start(profileForm) }}
{{ form_widget(profileForm) }}
{{ form_end(profileForm) }}
{% endblock %}The theme applies to profileForm and its children in this template. Another form on the same page can use a different theme declaration.
Use global themes only for shared structure
Symfony’s form theming guide distinguishes global themes from themes applied to one form. Put truly shared blocks in twig.form_themes. Keep admin-only or account-only wrappers in separate templates and apply them with {% form_theme %} where each form is rendered. The related form rendering guide shows how complete forms and individual rows are rendered.
Form-specific themes are searched before global themes, so blocks not defined in the selected theme fall back to the global set. If you add the only keyword, global and built-in themes are disabled; explicitly import a base such as form_div_layout.html.twig or the form may lose essential blocks.
Reduce repetition without hiding the active theme
The theme declaration needs the actual form variable, so a parent layout cannot safely guess every child template’s form name. Keep a small page template for each form, or include a rendering partial that receives both the form and the chosen theme. Avoid changing a global theme according to the current route because that makes rendering dependent on hidden request state.
Put shared field blocks in a base theme and import or extend them from area-specific themes. Use form block prefixes for reusable type-level changes instead of copying page-specific block names. This keeps a custom address or money field consistent while still allowing each dashboard to wrap rows differently.
Test labels, errors, help text, collections, CSRF fields, and nested forms in each area. Render with form_end() or form_rest() so hidden fields are not accidentally omitted. When several forms share a page, declare the intended theme for each one and verify validation errors after submission, not only the initial page.
Continue with Symfony service configuration, passing controller data to views, and client-side form validation.