TTikotok V4
This commit is contained in:
96
greenlns-landing/lib/localeRoutes.ts
Normal file
96
greenlns-landing/lib/localeRoutes.ts
Normal file
@@ -0,0 +1,96 @@
|
||||
import type { Lang } from '@/lib/i18n'
|
||||
|
||||
/**
|
||||
* Zentrale Sprach-Architektur.
|
||||
*
|
||||
* `routeGroups`: echte Übersetzungspaare. Sie steuern den Sprachumschalter
|
||||
* UND erzeugen die hreflang-Alternates in der Metadata.
|
||||
*
|
||||
* `fuzzyTargets`: thematisch nächstliegende Seite, wenn es keine echte
|
||||
* Übersetzung gibt. Nur der Umschalter nutzt sie — hreflang ignoriert sie,
|
||||
* damit Google keine falschen Übersetzungspaare gemeldet bekommt.
|
||||
*
|
||||
* Neue Subpage? Echte Übersetzung in routeGroups eintragen, sonst
|
||||
* fuzzyTargets ergänzen (oder weglassen, dann geht's zur Locale-Startseite).
|
||||
*/
|
||||
const routeGroups: Partial<Record<Lang, string>>[] = [
|
||||
{ de: '/', en: '/en', es: '/es' },
|
||||
{ de: '/pflanzen-erkennen-app', en: '/plant-identifier-app', es: '/es/identificador-de-plantas' },
|
||||
{ de: '/blumen-scanner', en: '/flower-scanner' },
|
||||
{ de: '/pflanzen-bestimmen', en: '/identify-plant-photo' },
|
||||
{ de: '/zimmerpflanzen-bestimmen', en: '/houseplant-identifier' },
|
||||
{ de: '/pflanzen-pflege-app', en: '/plant-care-app', es: '/es/app-para-cuidar-plantas' },
|
||||
{ de: '/pflanzen-krankheiten-erkennen', en: '/plant-disease-identifier', es: '/es/diagnosticar-enfermedades-plantas' },
|
||||
{ de: '/pflanzen-erkennen-kostenlos', en: '/best-plant-identification-app' },
|
||||
{ en: '/plant-scanner', es: '/es/escaner-de-plantas' },
|
||||
{ de: '/vs/google-lens', es: '/es/comparar/google-lens' },
|
||||
]
|
||||
|
||||
const fuzzyTargets: Record<string, Partial<Record<Lang, string>>> = {
|
||||
'/blumen-scanner': { es: '/es/escaner-de-plantas' },
|
||||
'/flower-scanner': { es: '/es/escaner-de-plantas' },
|
||||
'/plant-scanner': { de: '/blumen-scanner' },
|
||||
'/pflanzen-bestimmen': { es: '/es/identificador-de-plantas' },
|
||||
'/identify-plant-photo': { es: '/es/identificador-de-plantas' },
|
||||
'/zimmerpflanzen-bestimmen': { es: '/es/identificador-de-plantas' },
|
||||
'/houseplant-identifier': { es: '/es/identificador-de-plantas' },
|
||||
'/pflanzen-erkennen-kostenlos': { es: '/es/identificador-de-plantas' },
|
||||
'/best-plant-identification-app': { es: '/es/identificador-de-plantas' },
|
||||
'/giess-erinnerung-app': { en: '/plant-care-app', es: '/es/app-para-cuidar-plantas' },
|
||||
'/plant-health-app': { de: '/pflanzen-krankheiten-erkennen', es: '/es/diagnosticar-enfermedades-plantas' },
|
||||
'/succulent-identifier': { de: '/zimmerpflanzen-bestimmen', es: '/es/identificador-de-plantas' },
|
||||
'/es/escaner-de-plantas': { de: '/blumen-scanner' },
|
||||
'/es/identificador-de-plantas': { de: '/pflanzen-erkennen-app' },
|
||||
'/vs/picturethis': { de: '/pflanzen-erkennen-app', es: '/es/identificador-de-plantas' },
|
||||
'/vs/plantum': { de: '/pflanzen-erkennen-app', es: '/es/identificador-de-plantas' },
|
||||
'/vs/inaturalist': { de: '/pflanzen-erkennen-app', es: '/es/identificador-de-plantas' },
|
||||
}
|
||||
|
||||
/** Seiten, die in allen Sprachen unter derselben URL leben (Client-Übersetzung). */
|
||||
const sharedPaths = new Set(['/support', '/imprint', '/privacy', '/terms'])
|
||||
|
||||
export const localeHome: Record<Lang, string> = { de: '/', en: '/en', es: '/es' }
|
||||
|
||||
const englishPaths = new Set([
|
||||
'/en',
|
||||
'/best-plant-identification-app',
|
||||
'/plant-identifier-app',
|
||||
'/plant-scanner',
|
||||
'/flower-scanner',
|
||||
'/houseplant-identifier',
|
||||
'/succulent-identifier',
|
||||
'/identify-plant-photo',
|
||||
'/plant-disease-identifier',
|
||||
'/plant-health-app',
|
||||
'/plant-care-app',
|
||||
])
|
||||
|
||||
export function getLocaleForPath(pathname: string): Lang {
|
||||
if (pathname === '/es' || pathname.startsWith('/es/')) return 'es'
|
||||
if (pathname === '/vs/google-lens') return 'de'
|
||||
if (englishPaths.has(pathname) || pathname.startsWith('/vs/')) return 'en'
|
||||
return 'de'
|
||||
}
|
||||
|
||||
function findGroup(pathname: string): Partial<Record<Lang, string>> | undefined {
|
||||
return routeGroups.find((group) => Object.values(group).includes(pathname))
|
||||
}
|
||||
|
||||
/** Ziel-URL beim Sprachwechsel: Übersetzung, thematischer Fallback oder Locale-Home. */
|
||||
export function getAlternatePath(pathname: string, target: Lang): string {
|
||||
if (sharedPaths.has(pathname)) return pathname
|
||||
if (getLocaleForPath(pathname) === target) return pathname
|
||||
return findGroup(pathname)?.[target] ?? fuzzyTargets[pathname]?.[target] ?? localeHome[target]
|
||||
}
|
||||
|
||||
/** hreflang-Alternates für die Metadata einer Seite (nur echte Übersetzungen). */
|
||||
export function getHreflangAlternates(pathname: string): Record<string, string> | undefined {
|
||||
const group = findGroup(pathname)
|
||||
if (!group || Object.keys(group).length < 2) return undefined
|
||||
return {
|
||||
...(group.de && { de: group.de }),
|
||||
...(group.en && { en: group.en }),
|
||||
...(group.es && { es: group.es }),
|
||||
'x-default': group.de ?? group.en ?? '/',
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user