- Published on
Add Navigation Icons to TYPO3
- Authors

- Name
- Susanne Moog
Navigation icons can be a great addition to your TYPO3 website, providing a visual representation of different pages in the navigation menu. This guide shows two approaches to add a per-page navigation icon field to the TYPO3 backend and how to use it in your frontend templates.
Simplest Way
Step 1: Prepare the Database
Create or modify the <your-ext>/ext_tables.sql file and add a new field to the pages table:
CREATE TABLE pages
(
nav_icon varchar(255) DEFAULT '' NOT NULL,
);
Step 2: Prepare the Language Label
In your extension's <your-ext>/Resources/Private/Language/Backend.xlf file, add a label for the new field:
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<xliff version="1.0">
<file source-language="en" datatype="plaintext" original="messages" date="2023-08-01T09:11:39Z" product-name="theme">
<header />
<body>
<trans-unit id="field.nav_icon">
<source>Navigation Icon</source>
</trans-unit>
</body>
</file>
</xliff>
Step 3: Add TCA Configuration
Add the TCA for the new nav_icon field in Configuration/TCA/Overrides/pages.php:
<?php
$GLOBALS['TCA']['pages']['columns'] = array_replace_recursive(
$GLOBALS['TCA']['pages']['columns'],
[
'nav_icon' => [
'label' => 'LLL:EXT:theme/Resources/Private/Language/Backend.xlf:field.nav_icon',
'config' => [
'type' => 'select',
'renderType' => 'selectSingle',
'fileFolderConfig' => [
'folder' => 'EXT:theme/Resources/Public/Icons/Navigation/',
'allowedExtensions' => 'svg',
],
'fieldWizard' => [
'selectIcons' => [
'disabled' => false,
],
],
],
'l10n_mode' => 'exclude',
],
]
);
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addToAllTCAtypes('pages', 'nav_icon', '1,3,4', 'after:nav_title');
More Control over Values
The above method returns only the SVG name as the value. If you want more control over the values stored, you can use the itemsProcFunc option in TCA to dynamically generate the list of icons.
Step 1: Update TCA Configuration
Modify the TCA configuration for the nav_icon field:
<?php
$GLOBALS['TCA']['pages']['columns'] = array_replace_recursive(
$GLOBALS['TCA']['pages']['columns'],
[
'nav_icon' => [
'label' => 'LLL:EXT:theme/Resources/Private/Language/Backend.xlf:field.nav_icon',
'config' => [
'type' => 'select',
'renderType' => 'selectSingle',
'itemsProcFunc' => \YourVendor\Theme\Service\TcaIconService::class . '::__invoke',
'fieldWizard' => [
'selectIcons' => [
'disabled' => false,
],
],
],
'l10n_mode' => 'exclude',
],
]
);
Step 2: Implement the Icon Service
Create Classes/Service/TcaIconService.php in your extension:
<?php
declare(strict_types=1);
namespace YourVendor\Theme\Service;
use Symfony\Component\Finder\Finder;
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
final class TcaIconService
{
public function __invoke(&$params): void
{
$finder = new Finder();
$themePrefix = 'EXT:theme/';
$folderPath = 'Resources/Public/Icons/Navigation/';
$iconFolder = $themePrefix . $folderPath;
$finder->files()->in(ExtensionManagementUtility::extPath('theme') . $folderPath);
foreach ($finder as $file) {
$params['items'][] = [
'label' => $file->getFilenameWithoutExtension(),
'value' => $iconFolder . $file->getFilename(),
'icon' => $iconFolder . $file->getFilename(),
];
}
}
}
Accessing nav_icon in Frontend Template
Use the value in your Fluid or other frontend templates:
<img src="{data.nav_icon}" />
Or debug the value:
<f:debug>{page.data.nav_icon}</f:debug>
That’s it! You now have a flexible way to choose navigation icons per page in the TYPO3 backend and render them in your frontend.