import { useEffect } from 'react'; import { useLocation } from 'react-router-dom'; import { canonicalUrl, seoForPath, SITE_ORIGIN } from '../seo'; function upsertMeta(selector: string, attrs: Record, content: string) { let el = document.head.querySelector(selector) as HTMLMetaElement | null; if (!el) { el = document.createElement('meta'); for (const [k, v] of Object.entries(attrs)) el.setAttribute(k, v); document.head.appendChild(el); } el.setAttribute('content', content); } function upsertCanonical(href: string) { let el = document.head.querySelector('link[rel="canonical"]') as HTMLLinkElement | null; if (!el) { el = document.createElement('link'); el.rel = 'canonical'; document.head.appendChild(el); } el.href = href; } export function SeoHead() { const { pathname } = useLocation(); useEffect(() => { const seo = seoForPath(pathname); const url = seo.index ? canonicalUrl(seo.path) : `${SITE_ORIGIN}${pathname}`; document.title = seo.title; upsertMeta('meta[name="description"]', { name: 'description' }, seo.description); upsertMeta( 'meta[name="robots"]', { name: 'robots' }, seo.index ? 'index, follow' : 'noindex, follow', ); upsertCanonical(url); upsertMeta('meta[property="og:title"]', { property: 'og:title' }, seo.title); upsertMeta('meta[property="og:description"]', { property: 'og:description' }, seo.description); upsertMeta('meta[property="og:url"]', { property: 'og:url' }, url); upsertMeta('meta[name="twitter:title"]', { name: 'twitter:title' }, seo.title); upsertMeta('meta[name="twitter:description"]', { name: 'twitter:description' }, seo.description); }, [pathname]); return null; }