import React, { useEffect } from 'react'; // TODO: Update SITE_URL to your actual domain before deploying export const SITE_URL = 'https://knuthceramics.com'; export const SITE_NAME = 'KNUTH Ceramics'; const DEFAULT_OG_IMAGE = `${SITE_URL}/landingpage/artelier.png`; type Schema = Record; interface SEOProps { title: string; description: string; canonical?: string; schema?: Schema | Schema[]; ogImage?: string; ogType?: 'website' | 'article' | 'product'; } function setMeta(selector: string, attr: string, value: string) { let el = document.querySelector(selector); if (!el) { el = document.createElement('meta'); const [attrName, attrVal] = selector.replace('meta[', '').replace(']', '').split('="'); el.setAttribute(attrName, attrVal.replace('"', '')); document.head.appendChild(el); } el.setAttribute(attr, value); } const SEO: React.FC = ({ title, description, canonical, schema, ogImage = DEFAULT_OG_IMAGE, ogType = 'website', }) => { const schemaStr = schema ? JSON.stringify(schema) : null; useEffect(() => { const fullTitle = title.includes(SITE_NAME) ? title : `${title} | ${SITE_NAME}`; document.title = fullTitle; setMeta('meta[name="description"]', 'content', description); setMeta('meta[property="og:title"]', 'content', fullTitle); setMeta('meta[property="og:description"]', 'content', description); setMeta('meta[property="og:type"]', 'content', ogType); setMeta('meta[property="og:image"]', 'content', ogImage); setMeta('meta[property="og:site_name"]', 'content', SITE_NAME); setMeta('meta[name="twitter:card"]', 'content', 'summary_large_image'); setMeta('meta[name="twitter:title"]', 'content', fullTitle); setMeta('meta[name="twitter:description"]', 'content', description); setMeta('meta[name="twitter:image"]', 'content', ogImage); let canonicalEl = document.querySelector('link[rel="canonical"]'); if (!canonicalEl) { canonicalEl = document.createElement('link'); canonicalEl.setAttribute('rel', 'canonical'); document.head.appendChild(canonicalEl); } canonicalEl.setAttribute('href', canonical ?? `${SITE_URL}${window.location.pathname}`); // Remove previous page-level schemas, inject new ones document.querySelectorAll('script[data-seo="page"]').forEach(el => el.remove()); if (schemaStr) { const schemas = Array.isArray(JSON.parse(schemaStr)) ? JSON.parse(schemaStr) : [JSON.parse(schemaStr)]; schemas.forEach((s: Schema) => { const script = document.createElement('script'); script.setAttribute('type', 'application/ld+json'); script.setAttribute('data-seo', 'page'); script.textContent = JSON.stringify(s); document.head.appendChild(script); }); } return () => { document.querySelectorAll('script[data-seo="page"]').forEach(el => el.remove()); }; }, [title, description, canonical, ogImage, ogType, schemaStr]); return null; }; export default SEO;