feat: comprehensive SEO system with keywords and schema markup

- Add 4-locale keyword configurations (SR, EN, DE, FR)
- Create schema generators (Product, Organization, Breadcrumb)
- Add React components for JSON-LD rendering
- Implement caching for keyword performance
- Abstract all SEO logic for maintainability
This commit is contained in:
Unchained
2026-03-30 11:22:44 +02:00
parent 767afac606
commit 234b1f1739
17 changed files with 1957 additions and 0 deletions

View File

@@ -0,0 +1,39 @@
import Script from 'next/script';
import { SchemaType } from '@/lib/seo/schema/types';
interface JsonLdProps {
data: SchemaType | SchemaType[];
}
/**
* React component to render JSON-LD schema markup
* Uses Next.js Script component for proper loading
*
* @param data - Single schema object or array of schemas
* @returns Script component with JSON-LD
* @example
* <JsonLd data={productSchema} />
* <JsonLd data={[productSchema, breadcrumbSchema]} />
*/
export function JsonLd({ data }: JsonLdProps) {
// Handle single schema or array
const schemas = Array.isArray(data) ? data : [data];
return (
<>
{schemas.map((schema, index) => (
<Script
key={index}
id={`json-ld-${index}`}
type="application/ld+json"
strategy="afterInteractive"
dangerouslySetInnerHTML={{
__html: JSON.stringify(schema),
}}
/>
))}
</>
);
}
export default JsonLd;

View File

@@ -0,0 +1,41 @@
import { JsonLd } from './JsonLd';
import { generateOrganizationSchema, generateWebSiteSchema } from '@/lib/seo/schema/organizationSchema';
import { Locale } from '@/lib/seo/keywords/types';
interface OrganizationSchemaProps {
baseUrl: string;
locale: Locale;
logoUrl: string;
socialProfiles?: string[];
email?: string;
}
/**
* Organization schema component
* Renders Organization + WebSite JSON-LD schemas
*
* @param baseUrl - Site base URL
* @param locale - Current locale
* @param logoUrl - URL to organization logo
* @param socialProfiles - Array of social media profile URLs
* @param email - Contact email
*/
export function OrganizationSchema({
baseUrl,
locale,
logoUrl,
socialProfiles,
email,
}: OrganizationSchemaProps) {
const orgSchema = generateOrganizationSchema(baseUrl, locale, {
logoUrl,
socialProfiles,
email,
});
const websiteSchema = generateWebSiteSchema(baseUrl, locale);
return <JsonLd data={[orgSchema, websiteSchema]} />;
}
export default OrganizationSchema;

View File

@@ -0,0 +1,67 @@
import { JsonLd } from './JsonLd';
import { generateProductSchema, generateCategorizedProductSchema } from '@/lib/seo/schema/productSchema';
import { generateProductBreadcrumbs } from '@/lib/seo/schema/breadcrumbSchema';
import { Locale } from '@/lib/seo/keywords/types';
interface ProductSchemaProps {
baseUrl: string;
locale: Locale;
product: {
name: string;
slug: string;
description: string;
images: string[];
price: {
amount: number;
currency: string;
};
sku?: string;
availability?: 'InStock' | 'OutOfStock' | 'PreOrder';
};
category?: 'antiAging' | 'hydration' | 'glow' | 'sensitive' | 'natural' | 'organic';
rating?: {
value: number;
count: number;
};
includeBreadcrumbs?: boolean;
}
/**
* Product schema component
* Renders Product + BreadcrumbList JSON-LD schemas
*
* @param baseUrl - Site base URL
* @param locale - Current locale
* @param product - Product data object
* @param category - Optional category for enhanced targeting
* @param rating - Optional aggregate rating data
* @param includeBreadcrumbs - Whether to include breadcrumb schema (default: true)
*/
export function ProductSchema({
baseUrl,
locale,
product,
category,
rating,
includeBreadcrumbs = true,
}: ProductSchemaProps) {
// Generate product schema
const productSchema = category
? generateCategorizedProductSchema(baseUrl, locale, { ...product, rating }, category)
: generateProductSchema(baseUrl, locale, { ...product, rating });
// Generate breadcrumbs if requested
if (includeBreadcrumbs) {
const breadcrumbSchema = generateProductBreadcrumbs(
baseUrl,
locale,
product.name,
product.slug
);
return <JsonLd data={[productSchema, breadcrumbSchema]} />;
}
return <JsonLd data={productSchema} />;
}
export default ProductSchema;

View File

@@ -0,0 +1,9 @@
/**
* SEO React Components
* Structured data and metadata components
*/
// Schema components
export { JsonLd } from './JsonLd';
export { OrganizationSchema } from './OrganizationSchema';
export { ProductSchema } from './ProductSchema';