234b1f1739
- 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
149 lines
3.9 KiB
TypeScript
149 lines
3.9 KiB
TypeScript
import { Locale, LocaleKeywords } from '../types';
|
|
import { serbianKeywords } from '../locales/sr';
|
|
import { englishKeywords } from '../locales/en';
|
|
import { germanKeywords } from '../locales/de';
|
|
import { frenchKeywords } from '../locales/fr';
|
|
|
|
/**
|
|
* Cache for loaded keywords to avoid repeated imports
|
|
*/
|
|
const keywordsCache: Record<Locale, LocaleKeywords | null> = {
|
|
sr: null,
|
|
en: null,
|
|
de: null,
|
|
fr: null
|
|
};
|
|
|
|
/**
|
|
* Get all SEO keywords for a specific locale
|
|
* Uses caching for performance
|
|
*
|
|
* @param locale - The locale code ('sr', 'en', 'de', 'fr')
|
|
* @returns LocaleKeywords object with all keywords for that locale
|
|
* @example
|
|
* const keywords = getKeywords('sr');
|
|
* console.log(keywords.pages.home.primary); // ['prirodni serum za lice', ...]
|
|
*/
|
|
export function getKeywords(locale: Locale): LocaleKeywords {
|
|
// Return from cache if available
|
|
if (keywordsCache[locale]) {
|
|
return keywordsCache[locale]!;
|
|
}
|
|
|
|
// Load keywords based on locale
|
|
const keywordsMap: Record<Locale, LocaleKeywords> = {
|
|
sr: serbianKeywords,
|
|
en: englishKeywords,
|
|
de: germanKeywords,
|
|
fr: frenchKeywords
|
|
};
|
|
|
|
const keywords = keywordsMap[locale];
|
|
|
|
// Cache for future use
|
|
keywordsCache[locale] = keywords;
|
|
|
|
return keywords;
|
|
}
|
|
|
|
/**
|
|
* Get keywords for a specific page type
|
|
* Convenience function for page-level keyword access
|
|
*
|
|
* @param locale - The locale code
|
|
* @param pageType - The page type ('home', 'products', 'product', 'about', 'contact', 'checkout', 'blog')
|
|
* @returns PageKeywords for the specified page
|
|
* @example
|
|
* const homeKeywords = getPageKeywords('sr', 'home');
|
|
* console.log(homeKeywords.primary); // Primary keywords for homepage
|
|
*/
|
|
export function getPageKeywords(
|
|
locale: Locale,
|
|
pageType: keyof LocaleKeywords['pages']
|
|
) {
|
|
const keywords = getKeywords(locale);
|
|
return keywords.pages[pageType];
|
|
}
|
|
|
|
/**
|
|
* Get category-specific keywords
|
|
*
|
|
* @param locale - The locale code
|
|
* @param category - The category key ('antiAging', 'hydration', 'glow', 'sensitive', 'natural', 'organic')
|
|
* @returns Array of keywords for that category
|
|
*/
|
|
export function getCategoryKeywords(
|
|
locale: Locale,
|
|
category: keyof LocaleKeywords['categories']
|
|
): string[] {
|
|
const keywords = getKeywords(locale);
|
|
return keywords.categories[category];
|
|
}
|
|
|
|
/**
|
|
* Get content topic keywords for blog/article generation
|
|
*
|
|
* @param locale - The locale code
|
|
* @param contentType - Type of content ('educational', 'benefits', 'comparison', 'ingredients')
|
|
* @returns Array of content topic keywords
|
|
*/
|
|
export function getContentKeywords(
|
|
locale: Locale,
|
|
contentType: keyof LocaleKeywords['content']
|
|
): string[] {
|
|
const keywords = getKeywords(locale);
|
|
return keywords.content[contentType];
|
|
}
|
|
|
|
/**
|
|
* Get competitor keywords for comparison content
|
|
*
|
|
* @param locale - The locale code
|
|
* @param competitorType - Type of competitor data ('brands', 'comparisons', 'alternatives')
|
|
* @returns Array of competitor-related keywords
|
|
*/
|
|
export function getCompetitorKeywords(
|
|
locale: Locale,
|
|
competitorType: keyof LocaleKeywords['competitors']
|
|
): string[] {
|
|
const keywords = getKeywords(locale);
|
|
return keywords.competitors[competitorType];
|
|
}
|
|
|
|
/**
|
|
* Get brand information for the locale
|
|
*
|
|
* @param locale - The locale code
|
|
* @returns BrandKeywords with localized tagline, category, etc.
|
|
*/
|
|
export function getBrandKeywords(locale: Locale) {
|
|
const keywords = getKeywords(locale);
|
|
return keywords.brand;
|
|
}
|
|
|
|
/**
|
|
* Clear the keywords cache (useful for testing or hot-reloading)
|
|
*/
|
|
export function clearKeywordsCache(): void {
|
|
keywordsCache.sr = null;
|
|
keywordsCache.en = null;
|
|
keywordsCache.de = null;
|
|
keywordsCache.fr = null;
|
|
}
|
|
|
|
/**
|
|
* Get all available locales
|
|
*/
|
|
export function getAvailableLocales(): Locale[] {
|
|
return ['sr', 'en', 'de', 'fr'];
|
|
}
|
|
|
|
/**
|
|
* Validate if a locale is supported
|
|
*/
|
|
export function isValidLocale(locale: string): locale is Locale {
|
|
return ['sr', 'en', 'de', 'fr'].includes(locale);
|
|
}
|
|
|
|
export default getKeywords;
|