Files
landing/src/components/SEO/SEO.tsx
2026-07-30 17:49:58 -07:00

62 lines
1.8 KiB
TypeScript

import { useEffect } from 'react';
interface SEOProps {
title?: string;
description?: string;
keywords?: string;
canonical?: string;
}
export function SEO({
title = 'Rosetta — Private Messaging',
description = 'Private messaging built around strong encryption, local message history, and user-controlled identity.',
keywords = 'Rosetta, encrypted messaging, private messenger, secure chat',
canonical = 'https://rosetta.im/'
}: SEOProps) {
useEffect(() => {
document.title = title;
updateMetaTag('name', 'description', description);
updateMetaTag('name', 'keywords', keywords);
updateMetaTag('property', 'og:title', title);
updateMetaTag('property', 'og:description', description);
updateMetaTag('property', 'og:url', canonical);
updateMetaTag('name', 'twitter:title', title);
updateMetaTag('name', 'twitter:description', description);
updateMetaTag('name', 'twitter:url', canonical);
removeMetaTag('property', 'og:image');
removeMetaTag('name', 'twitter:image');
updateCanonical(canonical);
}, [title, description, keywords, canonical]);
return null;
}
function updateMetaTag(attr: string, name: string, content: string) {
let element = document.querySelector(`meta[${attr}="${name}"]`);
if (!element) {
element = document.createElement('meta');
element.setAttribute(attr, name);
document.head.appendChild(element);
}
element.setAttribute('content', content);
}
function removeMetaTag(attr: string, name: string) {
document.querySelector(`meta[${attr}="${name}"]`)?.remove();
}
function updateCanonical(href: string) {
let element = document.querySelector<HTMLLinkElement>('link[rel="canonical"]');
if (!element) {
element = document.createElement('link');
element.rel = 'canonical';
document.head.appendChild(element);
}
element.href = href;
}