diff --git a/typo3/sysext/seo/Classes/HrefLang/HrefLangGenerator.php b/typo3/sysext/seo/Classes/HrefLang/HrefLangGenerator.php
index fa86d030809663415174aefaa3468840b8ece553..646615454d6f1acdd999e9e72172b9775f63a382 100644
--- a/typo3/sysext/seo/Classes/HrefLang/HrefLangGenerator.php
+++ b/typo3/sysext/seo/Classes/HrefLang/HrefLangGenerator.php
@@ -17,8 +17,14 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Seo\HrefLang;
 
+use Psr\Http\Message\ServerRequestInterface;
+use TYPO3\CMS\Core\Context\Context;
+use TYPO3\CMS\Core\Context\LanguageAspectFactory;
+use TYPO3\CMS\Core\Domain\Repository\PageRepository;
 use TYPO3\CMS\Core\Http\Uri;
+use TYPO3\CMS\Core\Site\Entity\SiteInterface;
 use TYPO3\CMS\Core\Site\Entity\SiteLanguage;
+use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
 use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;
 use TYPO3\CMS\Frontend\DataProcessing\LanguageMenuProcessor;
@@ -60,16 +66,25 @@ class HrefLangGenerator
         $languages = $this->languageMenuProcessor->process($this->cObj, [], [], []);
         /** @var SiteLanguage $siteLanguage */
         $siteLanguage = $event->getRequest()->getAttribute('language');
+        $pageId = (int)$this->getTypoScriptFrontendController()->id;
+
         foreach ($languages['languagemenu'] as $language) {
             if ($language['available'] === 1 && !empty($language['link']) && $language['hreflang']) {
+                $page = $this->getTranslatedPageRecord($pageId, $language['languageId'], $event->getRequest());
+                if (!empty($page['canonical_link'])) {
+                    // do not set hreflang when canonical is set
+                    continue;
+                }
+
                 $href = $this->getAbsoluteUrl($language['link'], $siteLanguage);
                 $hrefLangs[$language['hreflang']] = $href;
             }
         }
 
         if (count($hrefLangs) > 1) {
-            $href = $this->getAbsoluteUrl($languages['languagemenu'][0]['link'], $siteLanguage);
-            $hrefLangs['x-default'] = $href;
+            if (array_key_exists($languages['languagemenu'][0]['hreflang'], $hrefLangs)) {
+                $hrefLangs['x-default'] = $hrefLangs[$languages['languagemenu'][0]['hreflang']];
+            }
         }
 
         $event->setHrefLangs($hrefLangs);
@@ -101,4 +116,24 @@ class HrefLangGenerator
     {
         return $GLOBALS['TSFE'];
     }
+
+    protected function getTranslatedPageRecord(int $pageId, int $languageId, ServerRequestInterface $request): array
+    {
+        $site = $request->getAttribute('site');
+        if (!$site instanceof SiteInterface) {
+            return $this->getTypoScriptFrontendController()->page;
+        }
+
+        $targetSiteLanguage = $site->getLanguageById($languageId);
+        $languageAspect = LanguageAspectFactory::createFromSiteLanguage($targetSiteLanguage);
+
+        $context = clone GeneralUtility::makeInstance(Context::class);
+        $context->setAspect('language', $languageAspect);
+
+        $pageRepository = GeneralUtility::makeInstance(PageRepository::class, $context);
+        if ($languageId > 0) {
+            return $pageRepository->getPageOverlay($pageId, $languageId);
+        }
+        return $pageRepository->getPage($pageId);
+    }
 }
diff --git a/typo3/sysext/seo/Tests/Functional/Fixtures/HrefLangScenario.yml b/typo3/sysext/seo/Tests/Functional/Fixtures/HrefLangScenario.yml
index cacb834888904205be81e85b23134927c3114f3a..0496f396238441b2d69a9a58d9a2c5487229d1e1 100644
--- a/typo3/sysext/seo/Tests/Functional/Fixtures/HrefLangScenario.yml
+++ b/typo3/sysext/seo/Tests/Functional/Fixtures/HrefLangScenario.yml
@@ -44,3 +44,11 @@ entities:
           languageVariants:
             - self: {id: 1101, title: 'DE: Willkommen', language: 1, slug: '/willkommen'}
             - self: {id: 1102, title: 'NL: Welkom', language: 3, slug: '/welkom'}
+        - self: {id: 1200, title: 'EN: Contact', slug: '/contact', canonical_link: 'https://www.typo3.org'}
+          languageVariants:
+            - self: {id: 1201, title: 'DE: Kontakt', language: 1, slug: '/kontakt'}
+            - self: {id: 1202, title: 'DE-CH: Kontakt', language: 2, slug: '/kontakt'}
+        - self: {id: 1300, title: 'EN: About', slug: '/about'}
+          languageVariants:
+            - self: {id: 1301, title: 'DE: Uber', language: 1, slug: '/uber'}
+            - self: {id: 1302, title: 'DE-CH: Uber', language: 2, slug: '/uber', canonical_link: 'https://acme.com/de/uber'}
diff --git a/typo3/sysext/seo/Tests/Functional/HrefLang/HrefLangGeneratorTest.php b/typo3/sysext/seo/Tests/Functional/HrefLang/HrefLangGeneratorTest.php
index 3f6188c0921f6b81b3396918c98ee3ebeac10baa..8275dbe960d101234eafc4361935516e1891ed5e 100644
--- a/typo3/sysext/seo/Tests/Functional/HrefLang/HrefLangGeneratorTest.php
+++ b/typo3/sysext/seo/Tests/Functional/HrefLang/HrefLangGeneratorTest.php
@@ -43,6 +43,7 @@ class HrefLangGeneratorTest extends FunctionalTestCase
     protected const LANGUAGE_PRESETS = [
         'EN' => ['id' => 0, 'title' => 'English', 'locale' => 'en_US.UTF8', 'iso' => 'en', 'hrefLang' => 'en-US', 'direction' => ''],
         'DE' => ['id' => 1, 'title' => 'German', 'locale' => 'de_DE.UTF8', 'iso' => 'de', 'hrefLang' => 'de-DE', 'direction' => ''],
+        'DE-CH' => ['id' => 2, 'title' => 'Swiss German', 'locale' => 'de_CH.UTF8', 'iso' => 'de', 'hrefLang' => 'de-CH', 'direction' => ''],
         'NL' => ['id' => 3, 'title' => 'Dutch', 'locale' => 'nl_NL.UTF8', 'iso' => 'nl', 'hrefLang' => '', 'direction' => ''],
     ];
 
@@ -68,6 +69,7 @@ class HrefLangGeneratorTest extends FunctionalTestCase
             [
                 $this->buildDefaultLanguageConfiguration('EN', '/'),
                 $this->buildLanguageConfiguration('DE', '/de'),
+                $this->buildLanguageConfiguration('DE-CH', '/de-ch'),
                 $this->buildLanguageConfiguration('NL', '/nl'),
             ]
         );
@@ -160,6 +162,28 @@ class HrefLangGeneratorTest extends FunctionalTestCase
                     '<link rel="alternate" hreflang="" href="https://acme.com/nl/welkom"/>',
                 ]
             ],
+            'English page with canonical' => [
+                'https://acme.com/contact',
+                [
+                    '<link rel="alternate" hreflang="de-DE" href="https://acme.com/de/kontakt"/>',
+                    '<link rel="alternate" hreflang="de-CH" href="https://acme.com/de-ch/kontakt"/>',
+                ],
+                [
+                    '<link rel="alternate" hreflang="en-US" href="https://acme.com/contact"/>',
+                    '<link rel="alternate" hreflang="x-default" href="https://acme.com/contact"/>',
+                ]
+            ],
+            'Swiss german page with canonical' => [
+                'https://acme.com/de-ch/uber',
+                [
+                    '<link rel="alternate" hreflang="en-US" href="https://acme.com/about"/>',
+                    '<link rel="alternate" hreflang="x-default" href="https://acme.com/about"/>',
+                    '<link rel="alternate" hreflang="de-DE" href="https://acme.com/de/uber"/>',
+                ],
+                [
+                    '<link rel="alternate" hreflang="de-CH" href="https://acme.com/de-ch/uber"/>',
+                ]
+            ],
         ];
     }