optimiser SEO et images, corriger age minimum inscription
This commit is contained in:
@@ -1,29 +1,52 @@
|
||||
import { useEffect } from 'react'
|
||||
import { useLocation } from 'react-router-dom'
|
||||
|
||||
// Domaine de production, utilisé pour construire des URLs absolues
|
||||
// (canonical, og:url) à partir du chemin de la route courante.
|
||||
const SITE_URL = 'https://www.dsp5-archi-o24a-4-5-g4.fr'
|
||||
|
||||
// Change la valeur d'un attribut sur le premier élément trouvé par le
|
||||
// sélecteur, et retourne de quoi la restaurer plus tard. N'écrit rien si
|
||||
// l'élément est absent du <head> (les balises de base vivent dans
|
||||
// index.html ; ce hook ne fait que les mettre à jour, jamais les créer).
|
||||
function setAttr(selector, attr, value) {
|
||||
if (value == null) return null
|
||||
const el = document.querySelector(selector)
|
||||
if (!el) return null
|
||||
const previous = el.getAttribute(attr)
|
||||
el.setAttribute(attr, value)
|
||||
return () => el.setAttribute(attr, previous ?? '')
|
||||
}
|
||||
|
||||
// Permet à une page de définir son propre <title>, sa meta description, son
|
||||
// URL canonique et ses balises Open Graph/Twitter le temps qu'elle est
|
||||
// affichée. La SPA n'a qu'un seul index.html : sans ce hook, toutes les
|
||||
// routes partagent les mêmes balises. Les valeurs précédentes sont
|
||||
// restaurées au démontage, donc quitter la page revient à l'état d'avant
|
||||
// (celui d'index.html, ou celui d'une page parente si elles s'enchaînent).
|
||||
export default function usePageMeta({ title, description, image } = {}) {
|
||||
const { pathname } = useLocation()
|
||||
|
||||
// Permet à une page de définir son propre <title>/<meta description> le
|
||||
// temps qu'elle est affichée. La SPA n'a qu'un seul index.html : sans ce
|
||||
// hook, toutes les routes partagent le même title/meta. Les valeurs
|
||||
// précédentes sont restaurées au démontage, donc quitter la page revient à
|
||||
// l'état d'avant (celui d'index.html, ou celui d'une page parente si elles
|
||||
// s'enchaînent).
|
||||
export default function usePageMeta({ title, description } = {}) {
|
||||
useEffect(() => {
|
||||
const previousTitle = document.title
|
||||
if (title) {
|
||||
document.title = title
|
||||
}
|
||||
if (title) document.title = title
|
||||
|
||||
const metaEl = document.querySelector('meta[name="description"]')
|
||||
const previousDescription = metaEl?.getAttribute('content') ?? null
|
||||
if (description && metaEl) {
|
||||
metaEl.setAttribute('content', description)
|
||||
}
|
||||
const url = `${SITE_URL}${pathname}`
|
||||
const restores = [
|
||||
setAttr('meta[name="description"]', 'content', description),
|
||||
setAttr('link[rel="canonical"]', 'href', url),
|
||||
setAttr('meta[property="og:title"]', 'content', title),
|
||||
setAttr('meta[property="og:description"]', 'content', description),
|
||||
setAttr('meta[property="og:url"]', 'content', url),
|
||||
setAttr('meta[property="og:image"]', 'content', image),
|
||||
setAttr('meta[name="twitter:title"]', 'content', title),
|
||||
setAttr('meta[name="twitter:description"]', 'content', description),
|
||||
setAttr('meta[name="twitter:image"]', 'content', image),
|
||||
].filter(Boolean)
|
||||
|
||||
return () => {
|
||||
document.title = previousTitle
|
||||
if (metaEl && previousDescription !== null) {
|
||||
metaEl.setAttribute('content', previousDescription)
|
||||
}
|
||||
restores.forEach((restore) => restore())
|
||||
}
|
||||
}, [title, description])
|
||||
}, [title, description, image, pathname])
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user