Fix alternate href

pull/2573/head
Jérémy Rialland 2023-04-11 19:37:43 +02:00 committed by Jérémy Rialland
parent 373e31c9de
commit 956a4149f3
2 changed files with 71 additions and 48 deletions

View File

@ -13,44 +13,39 @@ import { FooterColumn } from '@/design-system/footer/column'
import { Container, Grid } from '@/design-system/layout'
import { Link } from '@/design-system/typography/link'
import { Body } from '@/design-system/typography/paragraphs'
import { alternateLinks, useSitePaths } from '@/sitePaths'
import { alternatePathname, useSitePaths } from '@/sitePaths'
import InscriptionBetaTesteur from './InscriptionBetaTesteur'
import Privacy from './Privacy'
const hrefLangLink = alternateLinks()
const altPathname = alternatePathname()
export default function Footer() {
const { absoluteSitePaths } = useSitePaths()
const { pathname } = useLocation()
const { t, i18n } = useTranslation()
const language = i18n.language as 'fr' | 'en'
const currentPath = useLocation().pathname
const currentEnv = import.meta.env.MODE
const encodedUri =
typeof window !== 'undefined' &&
(currentEnv === 'production' || currentEnv === 'development'
? `${window.location.protocol}//${window.location.host}`
: '') + window.location.pathname
const uri =
currentEnv === 'production'
? (encodedUri || '').replace(/\/$/, '')
: encodedUri || ''
const hrefLink =
hrefLangLink[language][uri] ?? hrefLangLink[language][uri + '/']
const path = pathname.replace(/^\/(mon-entreprise|infrance)/, '')
const altLang = language === 'en' ? 'fr' : 'en'
const altHref =
(import.meta.env.DEV && typeof window !== 'undefined'
? language === 'en'
? '/mon-entreprise'
: '/infrance'
: '') + altPathname[language][path] ?? altPathname[language][path + '/']
const isFrenchMode = language === 'fr'
return (
<>
<Helmet>
{hrefLink && (
{altHref && (
<link
key={hrefLink.hrefLang}
key={altLang}
rel="alternate"
hrefLang={hrefLink.hrefLang}
href={hrefLink.href}
hrefLang={altLang}
href={altHref}
/>
)}
</Helmet>
@ -67,7 +62,7 @@ export default function Footer() {
: theme.colors.bases.tertiary[100]
}
>
<FeedbackButton key={`${currentPath}-feedback-key`} />
<FeedbackButton key={`${pathname}-feedback-key`} />
{language === 'en' && (
<Body>
This website is provided by the{' '}
@ -136,13 +131,13 @@ export default function Footer() {
<InscriptionBetaTesteur /> <Emoji emoji="💌" />
</StyledLi>
)}
{hrefLink && (
<StyledLi key={hrefLink.hrefLang}>
{altHref && (
<StyledLi key={altLang}>
<Grid container spacing={2}>
<Grid item>
<StyledButton
openInSameWindow
href={hrefLink.href}
href={altHref}
aria-disabled={isFrenchMode}
isDisabled={isFrenchMode}
aria-label={
@ -163,10 +158,11 @@ export default function Footer() {
</Grid>
<Grid item>
<StyledButton
href={hrefLink.href}
href={altHref}
openInSameWindow
lang="en"
aria-disabled={!isFrenchMode}
isDisabled={!isFrenchMode}
aria-label={
!isFrenchMode
? t('English version of the website enabled.')

View File

@ -321,30 +321,57 @@ export const generateSiteMap = (sitePaths: AbsoluteSitePaths): SiteMap =>
sitePaths
)
export const alternateLinks = () => {
const basePathFr =
import.meta.env.DEV && typeof window !== 'undefined'
? `http://${window.location.host}/mon-entreprise`
: import.meta.env.VITE_FR_BASE_URL ?? ''
export const alternatePathname = () => {
type Lang = 'fr' | 'en'
type Sitepath = { [k: string]: string | Sitepath }
type LangSitepath = { [k in Lang]: string }
type Return = { [k: string]: LangSitepath | Return }
const basePathEn =
import.meta.env.DEV && typeof window !== 'undefined'
? `http://${window.location.host}/infrance`
: import.meta.env.VITE_EN_BASE_URL ?? ''
const buildSitemap = (
lang: Lang,
sitePath: Sitepath,
initialValue: Return = {}
): Return =>
Object.entries(sitePath).reduce(
(acc, [key, path]): Return =>
typeof path === 'object'
? { ...acc, [key]: buildSitemap(lang, path, acc[key] as Return) }
: /\/:/.test(path)
? acc
: ({ ...acc, [key]: { ...acc[key], [lang]: path } } as Return),
initialValue
)
const enSiteMap = generateSiteMap(absoluteSitePaths.en).map(
(path) => basePathEn + encodeURI(path)
const buildPathname = (
sitemap: Return,
initialValue: Record<Lang, Record<string, string>> = { fr: {}, en: {} }
) =>
Object.values(sitemap).reduce(
(acc, obj): Record<Lang, Record<string, string>> =>
typeof obj === 'object' && ('fr' in obj || 'en' in obj)
? {
fr: {
...acc.fr,
...('fr' in obj
? { [obj.fr as string]: (obj.en || obj.fr) as string }
: null),
},
en: {
...acc.en,
...('en' in obj
? { [obj.en as string]: (obj.fr || obj.en) as string }
: null),
},
}
: buildPathname(obj, acc),
initialValue
)
return buildPathname(
buildSitemap(
'en',
absoluteSitePaths.en,
buildSitemap('fr', absoluteSitePaths.fr)
)
)
const frSiteMap = generateSiteMap(absoluteSitePaths.fr).map(
(path) => basePathFr + encodeURI(path)
)
return {
en: Object.fromEntries(
enSiteMap.map((key, i) => [key, { href: frSiteMap[i], hrefLang: 'fr' }])
),
fr: Object.fromEntries(
frSiteMap.map((key, i) => [key, { href: enSiteMap[i], hrefLang: 'en' }])
),
}
}