Feature: #107875 - Improved DocHeader layout and unified language selector
See forge#107875
Description
The TYPO3 backend document header (DocHeader) has been reorganized to provide a more consistent and intuitive user experience across all backend modules.
This feature includes the following improvements:
Unified language selector
All backend modules with multi-language support now use a consistent language selector in the top-right area of the DocHeader. This includes:
- Content > Layout
- Content > List
- Content > Preview
- Record editing (FormEngine)
Note
Some backend modules were renamed in TYPO3 v14.
The top-level module now called Content was formerly named Web.
The module Content > Layout was formerly called Web > Page.
For details, see: Feature: #107628 – Improved backend module naming and structure.
The language selector displays the currently selected language as the button text (for example "English", "German", and the special All languages) with a descriptive "Language:" prefix for screen readers. This provides immediate visual feedback about the active language while maintaining full accessibility.
The language selector now allows creating new page translations directly from the dropdown (except in Preview mode). The dropdown is organized with existing translations shown first, followed by a divider and a "Create new translation" section header. Languages that do not yet have a translation appear in this separate section.
Selecting a language from the "Create new translation" section will:
- Create the page translation via the DataHandler.
- Open the FormEngine to edit the newly created translation.
- Provide a consistent workflow across all modules.
Reorganized DocHeader layout
The DocHeader now has a more logical structure:
Top row (navigation bar):
- Left side: Breadcrumb navigation showing the current location
- Right side: Language selector (when applicable)
Second row (button bar):
- Left side, group 0: Module actions dropdown (when applicable)
- Left side, groups 1+: Additional action buttons and context-specific buttons (Save, Close, and so on)
- Right side: Functional buttons such as "Reload", "Bookmark", or "Clear cache"
Technical details
Module actions dropdown
Controllers can use the existing
Module method to automatically
create a module actions dropdown based on the module configuration:
$view = $this->moduleTemplateFactory->create($request);
$view->makeDocHeaderModuleMenu();
For backward compatibility, the MenuRegistry API is automatically converted to module actions dropdowns.
Language selector integration
The language selector is integrated via the
Doc method.
First, inject the
\TYPO3\ into your
controller:
use TYPO3\CMS\Backend\Template\Components\ComponentFactory;
public function __construct(
private readonly ComponentFactory $componentFactory,
) {}
Then build the language selector dropdown with language items:
// Get available site languages for the current page
$siteLanguages = $this->site->getAvailableLanguages($pageRecord, $backendUser);
$currentLanguageId = (int)$moduleData->get('language');
// Build dropdown button
$languageDropdown = $this->componentFactory->createDropDownButton()
->setLabel($languageService->sL('core.core:labels.language'))
->setShowLabelText(true)
->setShowActiveLabelText(true);
// Create dropdown items for each language
foreach ($siteLanguages as $siteLanguage) {
$languageId = $siteLanguage->getLanguageId();
$isActive = $currentLanguageId === $languageId;
// Build URL for language selection
$href = $this->uriBuilder->buildUriFromRoute('web_layout', [
'id' => $pageId,
'language' => $languageId,
]);
$item = $this->componentFactory->createDropDownRadio()
->setHref($href)
->setLabel($siteLanguage->getTitle())
->setIcon(
$this->iconFactory->getIcon($siteLanguage->getFlagIdentifier())
)
->setActive($isActive);
$languageDropdown->addItem($item);
}
$view->getDocHeaderComponent()->setLanguageSelector($languageDropdown);
The language selector component is automatically rendered in the top-right area of the DocHeader navigation bar.
Note
For advanced implementations that include "Create new translation"
functionality, refer to the
Page in EXT:backend.
The controller demonstrates how to separate existing translations from
languages that can be created, using
Drop and
Drop components to organize the dropdown menu.
Accessibility implementation
The
set method enables display of the active
item's label while maintaining accessibility. When enabled with
set, the button renders the dropdown's label in a
visually hidden span followed by the active item's label:
- Visual users see: "English" (active language)
- Screen reader users hear: "Language: English" (descriptive label + active language)
When
set, the accessibility information is provided
through aria-label and title attributes instead.
This pattern applies to all dropdown buttons in the DocHeader:
$dropdown->setLabel('Display mode') // Descriptive label for context
->setShowLabelText(true) // Show label text
->setShowActiveLabelText(true); // Show active item label
Impact
The changes provide a more consistent and intuitive user experience. Users can now create and switch between page translations directly from the DocHeader across all relevant modules, without needing to navigate to specific page areas. The clear separation between existing translations and languages that can be created improves discoverability and reduces confusion about which actions are available.
The language selector and module actions dropdowns now display the currently active selection as the button text, providing immediate visual feedback. Users can see at a glance which language is selected or which module action is active, without needing to open the dropdown.
Accessibility has been significantly improved through the use of descriptive labels rendered as visually hidden elements or aria-label attributes. Screen reader users now receive proper context about each dropdown's purpose (e.g., "Language:", "Display mode:", "Module actions") combined with the current selection, ensuring equal access to navigation functionality.
The module actions dropdown makes it immediately clear which module or action is currently active, and which alternatives are available. The dropdown is only shown when multiple options exist, reducing visual clutter. Removal of redundant back buttons in favor of consistent breadcrumb navigation further reduces visual noise.