dev #51
@@ -6,7 +6,7 @@
|
||||
<xhtml:link rel="alternate" hreflang="en-CH" href="https://3d-fab.ch/en" />
|
||||
<xhtml:link rel="alternate" hreflang="de-CH" href="https://3d-fab.ch/de" />
|
||||
<xhtml:link rel="alternate" hreflang="fr-CH" href="https://3d-fab.ch/fr" />
|
||||
<xhtml:link rel="alternate" hreflang="x-default" href="https://3d-fab.ch/it" />
|
||||
<xhtml:link rel="alternate" hreflang="x-default" href="https://3d-fab.ch/" />
|
||||
<changefreq>weekly</changefreq>
|
||||
<priority>1.0</priority>
|
||||
</url>
|
||||
@@ -16,7 +16,7 @@
|
||||
<xhtml:link rel="alternate" hreflang="en-CH" href="https://3d-fab.ch/en" />
|
||||
<xhtml:link rel="alternate" hreflang="de-CH" href="https://3d-fab.ch/de" />
|
||||
<xhtml:link rel="alternate" hreflang="fr-CH" href="https://3d-fab.ch/fr" />
|
||||
<xhtml:link rel="alternate" hreflang="x-default" href="https://3d-fab.ch/it" />
|
||||
<xhtml:link rel="alternate" hreflang="x-default" href="https://3d-fab.ch/" />
|
||||
<changefreq>weekly</changefreq>
|
||||
<priority>1.0</priority>
|
||||
</url>
|
||||
@@ -26,7 +26,7 @@
|
||||
<xhtml:link rel="alternate" hreflang="en-CH" href="https://3d-fab.ch/en" />
|
||||
<xhtml:link rel="alternate" hreflang="de-CH" href="https://3d-fab.ch/de" />
|
||||
<xhtml:link rel="alternate" hreflang="fr-CH" href="https://3d-fab.ch/fr" />
|
||||
<xhtml:link rel="alternate" hreflang="x-default" href="https://3d-fab.ch/it" />
|
||||
<xhtml:link rel="alternate" hreflang="x-default" href="https://3d-fab.ch/" />
|
||||
<changefreq>weekly</changefreq>
|
||||
<priority>1.0</priority>
|
||||
</url>
|
||||
@@ -36,7 +36,7 @@
|
||||
<xhtml:link rel="alternate" hreflang="en-CH" href="https://3d-fab.ch/en" />
|
||||
<xhtml:link rel="alternate" hreflang="de-CH" href="https://3d-fab.ch/de" />
|
||||
<xhtml:link rel="alternate" hreflang="fr-CH" href="https://3d-fab.ch/fr" />
|
||||
<xhtml:link rel="alternate" hreflang="x-default" href="https://3d-fab.ch/it" />
|
||||
<xhtml:link rel="alternate" hreflang="x-default" href="https://3d-fab.ch/" />
|
||||
<changefreq>weekly</changefreq>
|
||||
<priority>1.0</priority>
|
||||
</url>
|
||||
|
||||
@@ -117,6 +117,34 @@ describe('SeoService', () => {
|
||||
expect(ogLocaleCall?.[0].content).toBe('it_CH');
|
||||
});
|
||||
|
||||
it('uses the locale-adaptive root as x-default for home pages', () => {
|
||||
createService({
|
||||
url: '/de',
|
||||
data: {
|
||||
seoTitleKey: 'SEO.ROUTES.HOME.TITLE',
|
||||
seoDescriptionKey: 'SEO.ROUTES.HOME.DESCRIPTION',
|
||||
},
|
||||
translations: {
|
||||
'SEO.ROUTES.HOME.TITLE': '3D-Druck in Zürich | 3D fab',
|
||||
'SEO.ROUTES.HOME.DESCRIPTION': '3D-Druckservice in Zürich',
|
||||
},
|
||||
});
|
||||
|
||||
const alternates = Array.from(
|
||||
document.head.querySelectorAll(
|
||||
'link[rel="alternate"][data-seo-managed="true"]',
|
||||
),
|
||||
).map((node) => ({
|
||||
hreflang: node.getAttribute('hreflang'),
|
||||
href: node.getAttribute('href'),
|
||||
}));
|
||||
|
||||
expect(alternates).toContain({
|
||||
hreflang: 'x-default',
|
||||
href: `${document.location.origin}/`,
|
||||
});
|
||||
});
|
||||
|
||||
it('resolves translated route metadata for the active language', () => {
|
||||
const { meta, title } = createService({
|
||||
url: '/en/about',
|
||||
|
||||
@@ -105,7 +105,7 @@ export class SeoService {
|
||||
cleanPath,
|
||||
canonicalPath,
|
||||
alternates,
|
||||
alternates.it ?? canonicalPath,
|
||||
this.buildXDefaultPath(canonicalPath, alternates),
|
||||
lang,
|
||||
);
|
||||
}
|
||||
@@ -119,8 +119,7 @@ export class SeoService {
|
||||
const alternates = this.normalizeAlternatePaths(override.alternates);
|
||||
const xDefault =
|
||||
this.normalizeSeoPath(override.xDefault) ??
|
||||
alternates?.it ??
|
||||
canonicalPath;
|
||||
this.buildXDefaultPath(canonicalPath, alternates);
|
||||
|
||||
this.applySeoValues(
|
||||
title,
|
||||
@@ -162,7 +161,7 @@ export class SeoService {
|
||||
cleanPath,
|
||||
canonicalPath,
|
||||
alternates,
|
||||
alternates.it ?? canonicalPath,
|
||||
this.buildXDefaultPath(canonicalPath, alternates),
|
||||
lang,
|
||||
);
|
||||
}
|
||||
@@ -360,6 +359,25 @@ export class SeoService {
|
||||
}, {});
|
||||
}
|
||||
|
||||
private buildXDefaultPath(
|
||||
canonicalPath: string | null,
|
||||
alternates: SeoMap | null,
|
||||
): string | null {
|
||||
if (canonicalPath && this.isLocalizedHomePath(canonicalPath)) {
|
||||
return '/';
|
||||
}
|
||||
|
||||
return alternates?.it ?? canonicalPath;
|
||||
}
|
||||
|
||||
private isLocalizedHomePath(path: string): boolean {
|
||||
const segments = path.split('/').filter(Boolean);
|
||||
return (
|
||||
segments.length === 1 &&
|
||||
this.supportedLangSet.has(segments[0] as SupportedLang)
|
||||
);
|
||||
}
|
||||
|
||||
private normalizeAlternatePaths(
|
||||
paths: SeoMap | null | undefined,
|
||||
): SeoMap | null {
|
||||
|
||||
Reference in New Issue
Block a user