bgm hreflang 

Classification

bgm_hreflang

Version

13.4

Language

en

Description

An extension to add hreflang meta tags: <link rel="alternate" hreflang="" href="" />

Page translations are added automatically as hreflang tags.

Editors can configure other pages in the page properties which should be added as hreflang tags.

Keywords

link,alternate,hreflang,tag,meta,seo

Copyright

2022

Author

bgm websolutions GmbH & Co. KG <http://typo3.bgm-gmbh.de/> Marco Huber

Email

typo3@bgm-gmbh.de mail@marco-huber.de

License

This document is published under the Open Content License available from http://www.opencontent.org/opl.shtml

Rendered

Fri, 14 Nov 2025 14:36:32 +0000

The content of this document is related to TYPO3, a GNU/GPL CMS/Framework available from www.typo3.org.

Table of Contents

Introduction 

This is an extension to add hreflang meta tags: <link rel="alternate" hreflang="" href="" />

I call them hreflang tags! :-)

If you use the sys_languages for countries or if you have just one country with different languages, then there is no need for this extension. Then you can build the hreflang tags with simple TypoScript.

But if you have multiple countries with multiple languages, then you will need this extension. Because then you will have one page tree per country ("country branch") and TYPO3 CMS can not connect this country branches automatically. The editors have to say, which pages from the different country branches belong together.

More information about hreflang tags at Google: https://support.google.com/webmasters/answer/189077

Editors view

Prerequisites 

  • One page tree per country ("country branch")
  • Root of each country branch has the option "Use as Root Page" set
  • Crosslinks between the country branches work. Perhaps you have to set config.typolinkCheckRootline = 1 and config.typolinkEnableLinksAcrossDomains = 1 in your TypoScript setup.
  • If you have MountPages, try to set config.MP_disableTypolinkClosestMPvalue = 1 in your TypoScript setup.
  • If you activated the EXT:seo (typo3/cms-seo), you should disable it's hreflang generation
    • in TYPO3 9.5LTS with unset($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['TYPO3\CMS\Frontend\Page\PageGenerator']['generateMetaTags']['hreflang']); in the AdditionalConfiguration.php or your Theme-Extension's ext_localconf.php
    • in TYPO3 10.4LTS by not setting hreflang in your site config languages (or wait for EXT:bgm_hreflang version 5 :-))

Since version 4.0 you have to use the new page translation without the table "pages_language_overlay"!

Configuration 

The configuration is done in the AdditionalConfiguration.php or your Theme-Extension's ext_localconf.php:

$languageMapping = array(

	//"sys_language_uid" and "isolanguagecode" have to be unique in the array $languageMapping!
	sys_language_uid => isolanguagecode,

	//Example
	1 => 'de', //german
	11 => 'en', //english
	21 => 'it', //italian
	31 => 'fr', //french
);

$GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS']['bgm_hreflang']['countryMapping'] = array(

	//"pageid" is the rootpage of a country branch. It has to be unique in the array $countryMapping!
	pageid => array(

		//"isocountrycode" has to be unique in the array $countryMapping!
		'countryCode' => isocountrycode,

		//'$languageMapping + array(0 => isolanguagecode)' can be assigned more than once with the same "isolanguagecode" in the array countryMapping.
		'languageMapping' => $languageMapping + array(0 => isolanguagecode),

		//This optional 'additionalGetParameters' can be assigned to every language of the current country
		'additionalGetParameters' => array(
			//"sys_language_uid" has to be unique in the array $additionalGetParameters!
			sys_language_uid => additionalGetParameters,

			//Example
			1 => '&foo=bar&john=doe', //append &foo=bar&john=doe to the link to sys_language 1 in this country
		),

		//This optional 'domainName' can be assigned, if you would like to prepend a certain domain name before your urls.
		//It overrides an automatically assigned domain from the typolink function.
		'domainName' => 'https://www.domain.tld',

		//This is optional. You need this, if you want the Germany country branch to be used as Austrian country branch, too.
		'additionalCountries' => array(isocountrycode, isocountrycode, ...),
	),

	//Example
	61 => array( //International
		'countryCode' => 'en',
		'languageMapping' => $languageMapping + array(0 => 'en'),
		'additionalGetParameters' => array(
			1 => '&foo=bar&john=doe',
		),
		'domainName' => 'https://www.my-domain.com',
	),
	111 => array( //Germany and Austria
		'countryCode' => 'de',
		'languageMapping' => $languageMapping + array(0 => 'de'),
		'additionalGetParameters' => array(
			0 => '&foo=0',
			1 => '&foo=1',
			31 => '&foo=31',
		),
		'additionalCountries' => array('at'),
		'domainName' => 'https://www.my-domain.de',
	),
	161 => array( //Switzerland
		'countryCode' => 'ch',
		'languageMapping' => $languageMapping + array(0 => 'de'),
		'domainName' => 'https://www.my-domain.it',
	),
	211 => array( //Italy
		'countryCode' => 'it',
		'languageMapping' => $languageMapping + array(0 => 'it'),
	),
);

//If $_GET['L']==0, pages in this tree are rendered with hreflang="x-default", else only the isolanguagecode is used (without the isocountrycode)
$GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS']['bgm_hreflang']['defaultCountryId'] = 61;

//Cache is cleared in frontend for all related pages if no cache entry for the current page has been found.
//Here you can disable this behaviour, if you are sure the new DataHandler backend hook is enough cache clearing.
$GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS']['bgm_hreflang']['feature']['clearCacheInFrontent'] = true;
Copied!

And you need some TypoScript:

page.headerData.30 = USER
page.headerData.30 {
	userFunc = BGM\BgmHreflang\Utility\HreflangTags->renderFrontendList
}
Copied!

Usage 

Editors can connect the pages from the different country branches in the page properties.

Example 

Pagetree 

  • 61 International
    • 71 Page A
      • sys_language_uid 0 => english
    • 81 Page B
      • sys_language_uid 0 => english
    • 91 Page C
      • sys_language_uid 0 => english
    • 101 Page D
      • sys_language_uid 0 => english
      • sys_language_uid 1 => german
  • 111 Deutschland
    • 121 Seite A
      • sys_language_uid 0 => german
    • 131 Seite B
      • sys_language_uid 0 => german
    • 141 Seite C
      • sys_language_uid 0 => german
      • sys_language_uid 11 => english
    • 151 Seite D
      • sys_language_uid 0 => german
  • 161 Schweiz
    • 201 Seite A
      • sys_language_uid 0 => german
      • sys_language_uid 21 => italian
      • sys_language_uid 31 => french
    • 191 Seite B
      • sys_language_uid 0 => german
      • sys_language_uid 21 => italian
    • 181 Seite C
      • sys_language_uid 0 => german
      • sys_language_uid 31 => french
    • 171 Seite D
      • sys_language_uid 0 => german
  • 211 Italia
    • 251 Pagina A
      • sys_language_uid 0 => italian
    • 241 Pagina B
      • sys_language_uid 0 => italian
    • 231 Pagina C
      • sys_language_uid 0 => italian
    • 221 Pagina D
      • sys_language_uid 0 => italian
      • sys_language_uid 1 => german

Configuration 

$languageMapping = array(
	1 => 'de', //german
	11 => 'en', //english
	21 => 'it', //italian
	31 => 'fr', //french
);
$GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS']['bgm_hreflang']['countryMapping'] = array(
	//Example
	61 => array( //International
		'countryCode' => 'en',
		'languageMapping' => $languageMapping + array(0 => 'en'),
	),
	111 => array( //Germany and Austria
		'countryCode' => 'de',
		'languageMapping' => $languageMapping + array(0 => 'de'),
		'additionalCountries' => array('at'),
	),
	161 => array( //Switzerland
		'countryCode' => 'ch',
		'languageMapping' => $languageMapping + array(0 => 'de'),
	),
	211 => array( //Italy
		'countryCode' => 'it',
		'languageMapping' => $languageMapping + array(0 => 'it'),
	),
);
$GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS']['bgm_hreflang']['defaultCountryId'] = 61;
Copied!

Output 

1) The editor connected all A pages. So we have these hreflang tags on the A pages:

<link rel="alternate" hreflang="x-default" href="http://development.bgm.projects.localhost/index.php?id=71" />
<link rel="alternate" hreflang="de-de" href="http://development.bgm.projects.localhost/index.php?id=121" />
<link rel="alternate" hreflang="de-at" href="http://development.bgm.projects.localhost/index.php?id=121" />
<link rel="alternate" hreflang="de-ch" href="http://development.bgm.projects.localhost/index.php?id=201" />
<link rel="alternate" hreflang="it-ch" href="http://development.bgm.projects.localhost/index.php?id=201&L=21" />
<link rel="alternate" hreflang="fr-ch" href="http://development.bgm.projects.localhost/index.php?id=201&L=31" />
<link rel="alternate" hreflang="it-it" href="http://development.bgm.projects.localhost/index.php?id=251" />
Copied!

2) The editor connected the B pages 81, 131 and 241 (he has forgotten to connect the swiss B page 191 ;-)). So we have these hreflang tags on the B pages 81, 131 and 241:

<link rel="alternate" hreflang="x-default" href="http://development.bgm.projects.localhost/index.php?id=81" />
<link rel="alternate" hreflang="de-de" href="http://development.bgm.projects.localhost/index.php?id=131" />
<link rel="alternate" hreflang="de-at" href="http://development.bgm.projects.localhost/index.php?id=131" />
<link rel="alternate" hreflang="it-it" href="http://development.bgm.projects.localhost/index.php?id=241" />
Copied!

And we have these tags on the swiss B page 191:

<link rel="alternate" hreflang="de-ch" href="http://development.bgm.projects.localhost/index.php?id=191" />
<link rel="alternate" hreflang="it-ch" href="http://development.bgm.projects.localhost/index.php?id=191&L=21" />
Copied!

3) The international C page 91 is connected to the german C page 141. And the german C page 141 is connected to the italian C page 231.

<link rel="alternate" hreflang="de-de" href="http://development.bgm.projects.localhost/index.php?id=141" />
<link rel="alternate" hreflang="de-at" href="http://development.bgm.projects.localhost/index.php?id=141" />
<link rel="alternate" hreflang="it-it" href="http://development.bgm.projects.localhost/index.php?id=231" />
<link rel="alternate" hreflang="x-default" href="http://development.bgm.projects.localhost/index.php?id=91" />
Copied!

4) The swiss C page 181 is not connected to any other page and has a translation.

<link rel="alternate" hreflang="de-ch" href="http://development.bgm.projects.localhost/index.php?id=181" />
<link rel="alternate" hreflang="fr-ch" href="http://development.bgm.projects.localhost/index.php?id=181&L=31" />
Copied!

5) The international D page 101 is not connected to another page and has a translation.

<link rel="alternate" hreflang="x-default" href="http://development.bgm.projects.localhost/index.php?id=101" />
<link rel="alternate" hreflang="de" href="http://development.bgm.projects.localhost/index.php?id=101&L=1" />
Copied!

6) The german D page 151 is not connected to any other page and has no translation, but should be used for Austria, too.

<link rel="alternate" hreflang="de-de" href="http://development.bgm.projects.localhost/index.php?id=151" />
<link rel="alternate" hreflang="de-at" href="http://development.bgm.projects.localhost/index.php?id=151" />
Copied!

Developers 

Fixtures from functional tests 

To import the database fixtures to your ddev database you can mount the xml files to your ddev db container and then import them:

echo "TRUNCATE TABLE pages; LOAD XML LOCAL INFILE '/var/www/html/packages/bgm-hreflang/Tests/Functional/Fixtures/Database/pages.xml' INTO TABLE pages ROWS IDENTIFIED BY '<pages>';" | ddev import-db --no-drop
echo "TRUNCATE TABLE sys_language; LOAD XML LOCAL INFILE '/var/www/html/packages/bgm-hreflang/Tests/Functional/Fixtures/Database/sys_language.xml' INTO TABLE sys_language ROWS IDENTIFIED BY '<sys_language>';" | ddev import-db --no-drop
echo "TRUNCATE TABLE tx_bgmhreflang_page_page_mm; LOAD XML LOCAL INFILE '/var/www/html/packages/bgm-hreflang/Tests/Functional/Fixtures/Database/tx_bgmhreflang_page_page_mm.xml' INTO TABLE tx_bgmhreflang_page_page_mm ROWS IDENTIFIED BY '<tx_bgmhreflang_page_page_mm>';" | ddev import-db --no-drop
Copied!

Use this TypoScript setup on the root page:

page = PAGE
page.10 = USER
page.10 {
	userFunc = BGM\BgmHreflang\Utility\HreflangTags->renderFrontendList
	stdWrap.htmlSpecialChars = 1
	stdWrap.br = 1
}
Copied!

And use this in your AdditionalConfiguration.php:

$GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS']['bgm_hreflang'] = array(
	'countryMapping' => array(
		2 => array( //International
			'countryCode' => 'en',
			'languageMapping' => array(0 => 'en'),
			'domainName' => 'https://www.my-domain.com',
		),
		8 => array( //Germany and Austria
			'countryCode' => 'de',
			'languageMapping' => array(0 => 'de'),
			'additionalCountries' => array('at'),
		),
		14 => array( //Switzerland
			'countryCode' => 'ch',
			'languageMapping' => array(0 => 'de', 1 => 'it', 2 => 'fr',),
			'additionalGetParameters' => array(
				0 => '&foo=bar',
				2 => '&foo=bar&john=doe',
			),
		),
	),
	'defaultCountryId' => 2,
);
Copied!

Extend bgm_hreflang 

There are a lot of signals at different places in the code. Feel free to use them :-)

Example 

If you have product records in each country branch, but the EAN is the same, you could connect the products detail view automatically depending on the EAN:

//include this in your AdditionalConfiguration.php or your Theme-Extension's ext_localconf.php
\TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Extbase\\SignalSlot\\Dispatcher')
	->connect(
		'BGM\\BgmHreflang\\Utility\\HreflangTags',
		'frontend_beforeRenderSingleTag',
		'BGM\\BgmTheme\\SignalSlot\\HreflangTags',
		'getGetParametersForProducts'
	);
Copied!

See the implementation in the example script (EXT:bgm_hreflang/Documentation/Example/Products.php) <Example/Products.php>. Don't forget to connect the detail view pages in the backend! This class just adds the necessary GET parameters.

2.0.0 - 2015/05/26 

* 2015-05-26 [BUGFIX|FEATURE] Support for mountpoints
* 2015-05-26 [TASK] Update version number, update documentation, add changelog
Copied!

There have been some issues with mountpoints. There can be wrong entries in your tx_realurl_pathcache table because of this! This release fixes them. But I had to refactor a lot, so if you are using Signals/Slots there could be breaking changes. Test carefully!

There is still one open TODO: Test, what happens when there are nested mountpoints.

2.0.1 - 2015/08/10 

* 2015-08-10 [BUGFIX] Small bug with language code, Thanks to Sergio Catalá for reporting this issue (https://forge.typo3.org/issues/68851)
* 2015-08-10 CachingFramework is initialized automatically. Function was removed since 7.2
* 2015-08-10 Raise TYPO3 Core dependency
* 2015-08-10 Add composer json to fix autoload problems
Copied!

There is still one open TODO: Test, what happens when there are nested mountpoints.

2.0.2 - 2015/08/10 

* 2015-08-31 [TASK] Add a signal to manipulate full tag list. Thanks to Sergio Catalá for reporting this issue (https://forge.typo3.org/issues/69122)
* 2015-08-31 [BUGFIX] Use hreflangAttributes from Signal
* 2015-08-31 [TASK] Initialize SignalSlot dispatcher in constructor
* 2015-08-31 [TASK] Update version number, update documentation, add changelog
Copied!

There is still one open TODO: Test, what happens when there are nested mountpoints.

2.0.3 - 2016/05/03 

* 2016-01-27 Cast cacheIdentifier to string because the cache backend can't handle integers
* 2016-02-29 Add links to GitHub in the documentation
* 2016-03-01 Cleanup documentation
* 2016-03-01 Update documentation
* 2016-05-03 Raise TYPO3 Core dependency
* 2016-05-03 [BUGFIX] Set default cache group
* 2016-05-03 Fix typo in changelog
* 2016-10-25 Update changelog
* 2016-10-25 Fix caching configuration
* 2016-10-25 Update dependency and version; Deploy to TER
Copied!

There is still one open TODO: Test, what happens when there are nested mountpoints.

2.0.4 - 2017/02/06 

* 2017-02-06 Fix composer.json for TYPO3 6.2
* 2017-02-06 Change minimal TYPO3 version to 6.2
* 2017-02-06 Update version and changelog; Deploy to TER
* 2017-02-06 Really change version number; Deploy to TER
Copied!

There is still one open TODO: Test, what happens when there are nested mountpoints.

2.0.5 - 2017/09/13 

* 2017-09-13 [BUGFIX] Fix hreflang tags to default language
* 2017-10-23 [TASK] Remove unnecessary code from composer.json
* 2017-10-23 [TASK] Set dependency in composer.json
* 2017-10-23 [TASK] Set version number to 2.0.5
* 2017-10-23 [TASK] New configuration "domainName"
* 2017-10-23 [TASK] Deploy to TER
Copied!

There is still one open TODO: Test, what happens when there are nested mountpoints.

2.0.6 - 2017/10/24 

* 2017-10-24 [BUGFIX] Check if domainName has a scheme
* 2017-10-30 [TASK] Check if configuration for page language exists
* 2017-11-07 [BUGFIX] Unset more mountpoint stuff before generating URLs
* 2017-11-28 [TASK] Show domainName in BE
* 2017-11-28 [TASK] Use Hook in RealUrl to set host depending on domainName
* 2017-11-28 [TASK] New option additionalGetParameters per country per lanugage
* 2017-11-29 [TASK] Activate TCA show_thumbs
* 2018-01-12 [TASK] Deploy to TER - Last Version for TYPO3 6.2 and 7.6!
Copied!

There is still one open TODO: Test, what happens when there are nested mountpoints.

2.0.7 - 2018/01/15 

* 2018-01-15 [TASK] Introduce Functional Tests
* 2018-01-15 [BUGFIX] Reset $this->getParameter for each link
* 2018-01-15 [TASK] Deploy to TER
Copied!

There is still one open TODO: Test, what happens when there are nested mountpoints.

2.0.8 - 2018/01/15 

* 2018-01-15 [TASK] Raise version number
* 2018-01-15 [TASK] No need to test TYPO3 8.7 in 7.6 branch
* 2018-03-11 [TASK] Remove composer.lock
* 2018-03-01 [TASK] Fix GitLab CI cache key
Copied!

There is still one open TODO: Test, what happens when there are nested mountpoints.

3.0.0 - 2018/01/12 

* 2018-01-12 [TASK] Raise version number
* 2018-01-12 [TASK] Update documentation
* 2018-01-15 [TASK] Introduce Functional Tests
* 2018-01-15 [BUGFIX] Reset $this->getParameter for each link
* 2018-03-01 [TASK] Remove composer.lock
* 2018-03-01 [TASK] Fix GitLab CI cache key
* 2018-03-21 [BREAKING] Drop TYPO3 7.6 support
* 2018-03-29 [TASK] add "validRelation" so we can control output in Signal/Slot backend_beforeRenderSingleHreflangAttribute and frontend_beforeRenderSingleTag
Copied!

There is still one open TODO: Test, what happens when there are nested mountpoints.

3.0.1 - 2019/04/01 

* 2019-04-01 [TASK] Raise version number
* 2019-04-01 [TASK] Test with TYPO3 8 (php7.0-7.2) and TYPO3 9 (php7.2)
* 2019-04-01 [TASK] Update nimut/testingframework for php7.2
* 2019-04-01 [BUGFIX] Reset current renderedListItem
* 2019-04-01 [BUGFIX] Don't create empty list items
* 2019-04-01 [BUGFIX] Fix testing for TYPO3 9
* 2019-04-01 [BUGFIX] Fix for removed pages_language_overlay (Core change #82445)
* 2019-04-01 [BUGFIX] Fix for removed column workspace_preview in be_users (Core change #???)
* 2019-04-01 [BUGFIX] Fix for TYPO3 9 TCA changes
* 2019-04-01 [BUGFIX] Switch to doctrine for TYPO3 9
Copied!

There is still one open TODO: Test, what happens when there are nested mountpoints.

3.0.2 - 2019/04/01 

* 2019-04-01 [TASK] Raise version number
* 2019-10-23 [TASK] Check for existing configuration to prevent PHP warning.
* 2019-10-23 New version 3.0.2.
Copied!

There is still one open TODO: Test, what happens when there are nested mountpoints.

4.0.0 - 2020/10/27 

* 2020-10-27 [TASK] Set dev version number
* 2020-10-27 [TASK] Hardcoded composer 1.10 because replace.bgm_hreflang would break
* 2020-10-27 [TASK] Allow TYPO3 v10
* 2020-10-27 [TASK] Update nimut/testing-framework for v10
* 2020-10-27 [TASK] Drop support for outdated TYPO3 versions
* 2021-01-04 [TASK] Ignore composer.lock file created during running tests
* 2021-01-04 [TASK] Add .ddev for development and running tests
* 2021-01-04 [TASK] Remove to enable composer 2
* 2021-01-04 [TASK] Cleanup before and after functional tests
* 2021-01-04 [TASK] Update composer.json for updated testing framework
* 2021-01-04 [TASK] Update tests for TYPO3 9 site configs and core routing features
* 2021-01-04 [BUGFIX] Use protocol from site config if it's not set through config 'domainName'
* 2021-01-04 [TASK] Reuse functional test fixtures for manual testing
* 2021-01-04 [TASK] Register custom TCA node renderType instead of userFunc
* 2021-01-04 [TASK] Hide fields on page translations
* 2021-01-04 [BUGFIX] TCA type none needs no database field
* 2021-01-04 [TASK] Test related pages, too
* 2021-01-04 [BUGFIX] FollowUp bc14e5d55: We need L=0 to get URLs from translations to related default language
* 2021-01-05 [TASK] Fix BreakingChange in v10: Remove sysPage and use RootlineUtility
* 2021-01-05 [TASK] Don't use $GLOBALS['TSFE'] for uri building so we don't need to manipulate it
* 2021-01-05 [TASK] Fix BreakingChange in v10: CachingFramework flush by tag
* 2021-01-05 [TASK] Code style with php-cs
* 2021-01-05 [TASK] Manual code style fixes
* 2021-01-05 [TASK] Update changelog
* 2021-01-06 [TASK] Update documentation
* 2021-01-06 [TASK] Release version 4.0.0
Copied!

There is still one open TODO: Test, what happens when there are nested mountpoints.

4.0.1 - 2021/01/06 

* 2021-01-06 [TASK] Set to development version
* 2021-01-07 [TASK] Ignore relations to deleted pages
* 2021-01-07 [BUGFIX] Catch rootline errors
* 2021-01-07 [TASK] Test translated default country branch prepares issue #9
* 2021-01-07 [TASK] Test default country without countryCode, f.e. if defaultCountry is "International" (no real country)
* 2021-01-07 [BUGFIX] Fix translated country branches with additional countries
* 2021-01-07 [TASK] Documentation how to deactivate EXT:seo's hreflang tags (thanks to https://github.com/ZYZ64738)
* 2021-01-21 [TASK] Release version 4.0.1
Copied!

There is still one open TODO: Test, what happens when there are nested mountpoints.

4.0.2 - 2021/01/21 

* 2021-01-21 [TASK] Fix dependency version constraint for TER upload
* 2021-01-21 [TASK] Release version 4.0.2
Copied!

There is still one open TODO: Test, what happens when there are nested mountpoints.

4.0.3 - 2022/06/07 

* 2021-11-16 [BUGFIX] Fix composer dependencies (Thanks to Christian Wolfram)
* 2021-12-17 [BUGFIX] Fix parameter order in implode function (Thanks to Christian Wolfram)
* 2022-06-02 [TASK] Update dev-dependency to cs-fixer (Thanks to Daniel Goerz)
* 2022-06-07 [TASK] Remove require_dev section from composer.json
* 2022-06-07 [TASK] #21 - Don't allow to add relations in MM_opposite_field
Copied!

There is still one open TODO: Test, what happens when there are nested mountpoints.

4.0.4 - 2022/06/23 

* 2022-06-21 [BUGFIX] Reuse cache entry on related pages (Thanks to Hannes Lau)
* 2022-06-22 [BUGFIX] Fix error in additionalCountries translation handling and simplify code
* 2022-06-22 [TASK] Clear cache after changes in the backend (Thanks to Hannes Lau)
* 2022-06-22 [TASK] Feature flag to disable cache clearing in frontend (Thanks to Hannes Lau)
* 2022-06-22 [TASK] Hint to deactivate EXT:seo hreflang generation (Thanks to Sergio Catalá)
Copied!

There is still one open TODO: Test, what happens when there are nested mountpoints.

4.0.5 - 2022/06/23 

* 2022-06-23 [TASK] Compatibility with TYPO3 11.4LTS
Copied!

There is still one open TODO: Test, what happens when there are nested mountpoints.