I would like to show you my way how I integrate app icons cleanly into my own TYPO3 sitepackage.
As app icons have to be integrated into HTML in different ways depending on the manufacturer and browser, and a correspondingly large number of graphics and meta files are involved, it is advisable to use a generator for this. This saves you the work of researching all relevant and up-to-date files and HTML lines yourself with the respective manufacturers (Apple, Microsoft, Google, etc.). For example, I can recommend this generator here: https://realfavicongenerator.net/
After you have clicked through the GUI of the generator, you will receive these (or similar) files:
.
├── README.md
├── android-chrome-144x144.png
├── android-chrome-192x192.png
├── android-chrome-256x256.png
├── android-chrome-36x36.png
├── android-chrome-384x384.png
├── android-chrome-48x48.png
├── android-chrome-512x512.png
├── android-chrome-72x72.png
├── android-chrome-96x96.png
├── apple-touch-icon.png
├── browserconfig.xml
├── favicon-16x16.png
├── favicon-194x194.png
├── favicon-32x32.png
├── favicon.ico
├── html_code.html
├── mstile-144x144.png
├── mstile-150x150.png
├── mstile-310x150.png
├── mstile-310x310.png
├── mstile-70x70.png
├── safari-pinned-tab.svg
└── site.webmanifest
The installation instructions from the README.md
are kept quite simple. Here we are advised to store all files in the project root. However, we can do this more elegantly in the TYPO3 context 😉
Since I like to keep the project root clean, I would advise you to store the files in the usual TYPO3 structures of your sitepackage, e.g. under EXT:sitepackage/Resources/Public/Icons/Favicon/
.
You do not need to copy the following files into this directory:
README.md
→ This contains the installation instructionshtml_code.html
→ This contains the HTML code to be integratedbrowserconfig.xml
→ This is generated dynamically later using TypoScriptsite.webmanifest
→ This will be generated dynamically later using TypoScript
According to README.md
/html_code.html
the following code should be included:
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="194x194" href="/favicon-194x194.png">
<link rel="icon" type="image/png" sizes="192x192" href="/android-chrome-192x192.png">
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
<link rel="manifest" href="/site.webmanifest">
<link rel="mask-icon" href="/safari-pinned-tab.svg" color="#5bbad5">
<meta name="msapplication-config" content="/browserconfig.xml">
<meta name="msapplication-TileColor" content="#da532c">
<meta name="msapplication-TileImage" content="/mstile-144x144.png">
<meta name="theme-color" content="#ffffff">
Side note:
I added the line <meta name="msapplication-config" content="/browserconfig.xml">
to explicitly instruct IE to use the browserconfig.xml
from the root for security reasons. There are various discussions about this and I think better safe than sorry 😉.
This is integrated with the following TypoScript setup code:
page {
headerData {
10 = TEXT
10 {
value (
<link rel="apple-touch-icon" sizes="180x180" href="{path:EXT:sitepackage/Resources/Public/Icons/Favicon/apple-touch-icon.png}">
<link rel="icon" type="image/png" sizes="32x32" href="{path:EXT:sitepackage/Resources/Public/Icons/Favicon/favicon-32x32.png}">
<link rel="icon" type="image/png" sizes="194x194" href="{path:EXT:sitepackage/Resources/Public/Icons/Favicon/favicon-194x194.png}">
<link rel="icon" type="image/png" sizes="192x192" href="{path:EXT:sitepackage/Resources/Public/Icons/Favicon/android-chrome-192x192.png}">
<link rel="icon" type="image/png" sizes="16x16" href="{path:EXT:sitepackage/Resources/Public/Icons/Favicon/favicon-16x16.png}">
<link rel="manifest" href="/site.webmanifest">
<link rel="mask-icon" href="{path:EXT:sitepackage/Resources/Public/Icons/Favicon/safari-pinned-tab.svg}" color="#5bbad5">
<meta name="msapplication-config" content="/browserconfig.xml">
<meta name="msapplication-TileColor" content="#da532c">
<meta name="msapplication-TileImage" content="{path:EXT:sitepackage/Resources/Public/Icons/Favicon/mstile-144x144.png}">
<meta name="theme-color" content="#ffffff">
)
insertData = 1
}
}
}
It is assumed here that you have already defined page = PAGE
somewhere in order to define the default frontend rendering of your page under the theoretically freely selectable identifier page
. The use of page
for the default output is established practice. It is also assumed that you have not already made other specifications under page.headerData.10
. If you have, you can simply increase the Content Object Array Index 10
(recommended in increments of ten) up to a free space.
The specifications {path:EXT:sitepackage/Resources/Public/Icons/Favicon/<FILENAME>}
within the TEXT
value in combination with the specification insertData = 1
ensures that the files in Composer installations are dynamically referenced under /_assets/<HASH>/
. Here we have the situation that there is no longer a static path under which resources of the extension directory /Resources/Public/
can be called up (more here).
The classic favicon.ico
file for desktop browsers is generated but no longer explicitly provided in the embed code. Even if it is no longer necessary in most cases, I would still include this file, not least because TYPO3 provides its own TypoScript property for it.
page.shortcutIcon = EXT:sitepackage/Resources/Public/Icons/Favicon/favicon.ico
In the case of this file, however, you could also make an exception and consider placing it directly in the public root. There seem to be some tools (e.g. RSS readers) that cannot handle other paths.
Now we just have to make sure that site.webmanifest
and browserconfig.xml
are also callable in the root, although they do not actually exist there as files.
We achieve this by making two additions to the PageTypeSuffix
route enhancer mapping in our site configuration config/sites/<YOUR_IDENTIFIER>/config.yaml
:
browserconfig.xml: 2943879438
site.webmanifest: 3478304621
The page type numbers 2943879438
and 3478304621
are therefore mapped to the readable paths browserconfig.xml
and site.webmanifest
. The two numbers are freely chosen by me. The only important thing is that they are not used anywhere else. For example, the path sitemap.xml
of the SEO Core Extension already claims the type number 1533906435
.
The entire PageTypeSuffix
configuration block could end up looking like this (depending on the project):
routeEnhancers:
PageTypeSuffix:
type: PageType
default: /
index: ''
map:
/: 0
feed.rss: 9818
sitemap.xml: 1533906435
browserconfig.xml: 2943879438
site.webmanifest: 3478304621
Now we have to create these page types via TypoScript:
The XML file browserconfig.xml
contains icon meta information for Windows devices. It looks something like this:
<?xml version="1.0" encoding="utf-8"?>
<browserconfig>
<msapplication>
<tile>
<square70x70logo src="/mstile-70x70.png"/>
<square150x150logo src="/mstile-150x150.png"/>
<wide310x150logo src="/mstile-310x150.png"/>
<square310x310logo src="/mstile-310x310.png"/>
<square144x144logo src="/mstile-144x144.png"/>
<TileColor>#da532c</TileColor>
</tile>
</msapplication>
</browserconfig>
For example, we can create a corresponding page type with the TypoScript file EXT:sitepackage/Configuration/TypoScript/Setup/browserconfig.xml.typoscript
as follows:
browserconfig\.xml = PAGE
browserconfig\.xml {
typeNum = 2943879438
config {
disableAllHeaderCode = 1
additionalHeaders.10.header = Content-type:text/xml
admPanel = 0
debug = 0
}
10 = TEXT
10 {
wrap (
<?xml version="1.0" encoding="utf-8"?>
<browserconfig>
<msapplication>
<tile>
|
<TileColor>#da532c</TileColor>
</tile>
</msapplication>
</browserconfig>
)
value = square70x70, square150x150, wide310x150, square310x310, square144x144
split {
token = ,
cObjNum = 1
1.cObject = COA
1.cObject {
stdWrap.wrap = <|/>
10 = TEXT
10 {
current = 1
trim = 1
noTrimWrap = ||logo |
}
20 = TEXT
20 {
current = 1
trim = 1
replacement.10 {
search = #(square|wide)#i
replace =
useRegExp = 1
}
dataWrap = src="{path:EXT:sitepackage/Resources/Public/Icons/Favicon/mstile-|.png}"
}
}
}
}
}
We use the specification typeNum = 2943879438
to inform the system of the type number. In addition, we enter a few details under config
that enable the output as an XML document.
The JSON file site.webmanifest
(possibly also called manifest.json
→ pay attention to the file name in the rel="manifest"
link tag) contains icon meta information for Android devices. It looks something like this:
{
"name": "",
"short_name": "",
"icons": [
{
"src": "/android-chrome-36x36.png",
"sizes": "36x36",
"type": "image/png"
},
{
"src": "/android-chrome-48x48.png",
"sizes": "48x48",
"type": "image/png"
},
{
"src": "/android-chrome-72x72.png",
"sizes": "72x72",
"type": "image/png"
},
{
"src": "/android-chrome-96x96.png",
"sizes": "96x96",
"type": "image/png"
},
{
"src": "/android-chrome-144x144.png",
"sizes": "144x144",
"type": "image/png"
},
{
"src": "/android-chrome-192x192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "/android-chrome-256x256.png",
"sizes": "256x256",
"type": "image/png"
},
{
"src": "/android-chrome-384x384.png",
"sizes": "384x384",
"type": "image/png"
},
{
"src": "/android-chrome-512x512.png",
"sizes": "512x512",
"type": "image/png"
}
],
"theme_color": "#ffffff",
"background_color": "#ffffff",
"display": "standalone"
}
For example, we can create a corresponding page type with the TypoScript file EXT:sitepackage/Configuration/TypoScript/Setup/site.webmanifest.typoscript
as follows:
site\.webmanifest = PAGE
site\.webmanifest {
typeNum = 3478304621
config {
disableAllHeaderCode = 1
additionalHeaders.10.header = Content-type:application/json
admPanel = 0
debug = 0
}
10 = COA
10 {
stdWrap.wrap = {|}
10 = TEXT
10 {
dataWrap (
"name":"{siteLanguage:websiteTitle // site:websiteTitle}",
"short_name":"{siteLanguage:websiteTitle // site:websiteTitle}",
"icons":[|],
"theme_color":"#ffffff",
"background_color":"#ffffff",
"display":"standalone"
)
value = 36x36, 48x48, 72x72, 96x96, 144x144, 192x192, 256x256, 384x384, 512x512
split {
token = ,
wrap = {|},|*|{|},|*|{|}
cObjNum = 1
1.cObject = COA
1.cObject {
10 = TEXT
10 {
current = 1
trim = 1
dataWrap = "src":"{path:EXT:sitepackage/Resources/Public/Icons/Favicon/android-chrome-|.png}",
}
20 = TEXT
20 {
current = 1
trim = 1
wrap = "sizes":"|","type":"image/png"
}
}
}
}
}
}
Here, too, the type number typeNum = 3478304621
and the config
specifications for the output of a JSON file are specified.
The specifications
"name":"{siteLanguage:websiteTitle // site:websiteTitle}",
"short_name":"{siteLanguage:websiteTitle // site:websiteTitle}",
can be adapted to your needs if necessary. Currently, the website title used in the site configuration (language-dependent if necessary) is simply used here.
Done, have fun with the new dynamic app icons!
This is one of many ways in which you can output app icons in TYPO3. The nice thing about this solution is that the TypoScript files can be reused directly in the next project via "copy and paste". To do this, start the generator again with the same basic settings and new graphics, save the image files again under the path defined above, expand the site configuration, place the two new TypoScript files in the site package and, if necessary, adjust the extension key in the TypoScript.
Sebastian Klein, for example, offers an alternative approach for integrating the manifest JSON via middleware in the following Gist. This approach could certainly also be transferred to the browserconfig.xml
.
Now you are free to decide which way you want to go 😉
With TYPO3 v13 it is now possible to define static routes to assets. This can be used to let the HTML snippet, which is generated by realfavicongenerator.net untouched. These static routes can also be used for src in site.webmanifest.typoscript and browserconfig.xml.typoscript to avoid the dataWrap.
Only
page.shortcutIcon
still needs theEXT:
syntax.