google search index
All checks were successful
CI — Website / Website — typecheck, build (pull_request) Successful in 57s
All checks were successful
CI — Website / Website — typecheck, build (pull_request) Successful in 57s
This commit is contained in:
47
packages/website/src/components/SeoHead.tsx
Normal file
47
packages/website/src/components/SeoHead.tsx
Normal file
@@ -0,0 +1,47 @@
|
||||
import { useEffect } from 'react';
|
||||
import { useLocation } from 'react-router-dom';
|
||||
import { canonicalUrl, seoForPath, SITE_ORIGIN } from '../seo';
|
||||
|
||||
function upsertMeta(selector: string, attrs: Record<string, string>, 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;
|
||||
}
|
||||
Reference in New Issue
Block a user