Add SeoHead component with canonical, hreflang, OG, Twitter, and JSON-LD

This commit is contained in:
2026-04-15 00:20:40 +03:00
parent 599f35f14a
commit bb50e63866
+83
View File
@@ -0,0 +1,83 @@
import type { Language } from "@/i18n/resolver";
import { JsonLdRenderer } from "@/shared/seo/json-ld.js";
import type { Thing } from "schema-dts";
export interface SeoHeadProps {
title: string;
description: string;
canonical: string;
hreflang: Array<{ lang: Language | "x-default"; href: string }>;
og: {
title: string;
description: string;
url: string;
image: string;
type: "website" | "article";
locale: string;
siteName: string;
};
twitter?: {
card: "summary" | "summary_large_image";
title?: string;
description?: string;
image?: string;
};
jsonLd?: Thing | Thing[];
noindex?: boolean;
}
/**
* Renders the full SEO <head> fragment: title, meta description, canonical,
* hreflang alternates, Open Graph tags, Twitter Card tags, and JSON-LD.
*/
export function SeoHead({
title,
description,
canonical,
hreflang,
og,
twitter,
jsonLd,
noindex,
}: SeoHeadProps): JSX.Element {
return (
<>
<title>{title}</title>
<meta name="description" content={description} />
<link rel="canonical" href={canonical} />
{noindex && <meta name="robots" content="noindex,nofollow" />}
{/* Hreflang alternates */}
{hreflang.map((entry) => (
<link
key={entry.lang}
rel="alternate"
hrefLang={entry.lang}
href={entry.href}
/>
))}
{/* Open Graph */}
<meta property="og:title" content={og.title} />
<meta property="og:description" content={og.description} />
<meta property="og:url" content={og.url} />
<meta property="og:image" content={og.image} />
<meta property="og:type" content={og.type} />
<meta property="og:locale" content={og.locale} />
<meta property="og:site_name" content={og.siteName} />
{/* Twitter Card */}
{twitter && (
<>
<meta name="twitter:card" content={twitter.card} />
{twitter.title && <meta name="twitter:title" content={twitter.title} />}
{twitter.description && <meta name="twitter:description" content={twitter.description} />}
{twitter.image && <meta name="twitter:image" content={twitter.image} />}
</>
)}
{/* JSON-LD */}
{jsonLd && <JsonLdRenderer data={jsonLd} />}
</>
);
}