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:
79
src/lib/seo/schema/organizationSchema.ts
Normal file
79
src/lib/seo/schema/organizationSchema.ts
Normal file
@@ -0,0 +1,79 @@
|
||||
import { OrganizationSchema, WebSiteSchema } from './types';
|
||||
import { getBrandKeywords } from '../keywords';
|
||||
import { Locale } from '../keywords/types';
|
||||
|
||||
interface OrganizationData {
|
||||
logoUrl: string;
|
||||
socialProfiles?: string[];
|
||||
email?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate Organization schema (JSON-LD)
|
||||
* Pure function - takes data, returns schema object
|
||||
*
|
||||
* @param baseUrl - Site base URL
|
||||
* @param locale - Locale code
|
||||
* @param data - Organization data (logo, social links, etc.)
|
||||
* @returns OrganizationSchema object
|
||||
*/
|
||||
export function generateOrganizationSchema(
|
||||
baseUrl: string,
|
||||
locale: Locale,
|
||||
data: OrganizationData
|
||||
): OrganizationSchema {
|
||||
const brandKeywords = getBrandKeywords(locale);
|
||||
|
||||
const schema: OrganizationSchema = {
|
||||
'@context': 'https://schema.org',
|
||||
'@type': 'Organization',
|
||||
name: brandKeywords.companyName,
|
||||
url: baseUrl,
|
||||
logo: data.logoUrl,
|
||||
description: brandKeywords.tagline,
|
||||
};
|
||||
|
||||
// Add social profiles if provided
|
||||
if (data.socialProfiles && data.socialProfiles.length > 0) {
|
||||
schema.sameAs = data.socialProfiles;
|
||||
}
|
||||
|
||||
// Add contact point if email provided
|
||||
if (data.email) {
|
||||
schema.contactPoint = [{
|
||||
'@type': 'ContactPoint',
|
||||
contactType: 'customer service',
|
||||
email: data.email,
|
||||
availableLanguage: [locale.toUpperCase()],
|
||||
}];
|
||||
}
|
||||
|
||||
return schema;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate WebSite schema (JSON-LD)
|
||||
* Includes search action for site search
|
||||
*
|
||||
* @param baseUrl - Site base URL
|
||||
* @param locale - Locale code
|
||||
* @returns WebSiteSchema object
|
||||
*/
|
||||
export function generateWebSiteSchema(
|
||||
baseUrl: string,
|
||||
locale: Locale
|
||||
): WebSiteSchema {
|
||||
const brandKeywords = getBrandKeywords(locale);
|
||||
|
||||
return {
|
||||
'@context': 'https://schema.org',
|
||||
'@type': 'WebSite',
|
||||
name: brandKeywords.companyName,
|
||||
url: baseUrl,
|
||||
potentialAction: {
|
||||
'@type': 'SearchAction',
|
||||
target: `${baseUrl}/search?q={search_term_string}`,
|
||||
'query-input': 'required name=search_term_string',
|
||||
},
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user