NebulaCloud/lib/seo-utils.ts
2025-09-15 17:28:58 +08:00

89 lines
2.6 KiB
TypeScript

import { Locale, locales, defaultLocale } from './i18n';
import { getTranslations } from './translations';
export function updateDocumentMeta(locale: Locale) {
const translations = getTranslations(locale);
// Update document title
document.title = translations.meta.title;
// Update meta description
updateMetaTag('description', translations.meta.description);
// Update HTML lang attribute
document.documentElement.lang = locale;
}
function updateMetaTag(name: string, content: string) {
let meta = document.querySelector(`meta[name="${name}"]`) as HTMLMetaElement;
if (!meta) {
meta = document.createElement('meta');
meta.name = name;
document.head.appendChild(meta);
}
meta.content = content;
}
export function generateAlternateLinks(pathname: string, baseUrl: string = '') {
return locales.map((locale) => ({
hrefLang: locale,
href:
locale === defaultLocale ? `${baseUrl}${pathname}` : `${baseUrl}/${locale}${pathname}`,
}));
}
export function generateCanonicalUrl(pathname: string, locale: Locale, baseUrl: string = '') {
return locale === defaultLocale ? `${baseUrl}${pathname}` : `${baseUrl}/${locale}${pathname}`;
}
export function generateStructuredData(
type: 'WebSite' | 'BlogPosting' | 'Organization',
data: any,
locale: Locale,
) {
const baseUrl = process.env.NEXT_PUBLIC_BASE_URL || 'https://your-domain.com';
const translations = getTranslations(locale);
const baseStructuredData = {
'@context': 'https://schema.org',
'@type': type,
};
switch (type) {
case 'WebSite':
return {
...baseStructuredData,
name: translations.meta.title,
description: translations.meta.description,
url: baseUrl,
inLanguage: locale,
availableLanguage: locales,
};
case 'BlogPosting':
return {
...baseStructuredData,
headline: data.title,
description: data.excerpt,
author: {
'@type': 'Person',
name: data.author,
},
datePublished: data.date,
dateModified: data.date,
inLanguage: locale,
};
case 'Organization':
return {
...baseStructuredData,
name: translations.meta.title,
description: translations.meta.description,
url: baseUrl,
};
default:
return baseStructuredData;
}
}