138 lines
5.3 KiB
TypeScript
Raw Normal View History

2025-09-16 15:24:39 +08:00
'use client';
import { useEffect } from 'react';
interface TDKProps {
title: string;
description: string;
keywords: string;
lang: string;
}
export default function TDK({ title, description, keywords, lang }: TDKProps) {
useEffect(() => {
// Update document title
document.title = title;
// Update meta description
let metaDesc = document.querySelector('meta[name="description"]');
if (!metaDesc) {
metaDesc = document.createElement('meta');
metaDesc.setAttribute('name', 'description');
document.head.appendChild(metaDesc);
}
metaDesc.setAttribute('content', description);
// Update meta keywords
let metaKeywords = document.querySelector('meta[name="keywords"]');
if (!metaKeywords) {
metaKeywords = document.createElement('meta');
metaKeywords.setAttribute('name', 'keywords');
document.head.appendChild(metaKeywords);
}
metaKeywords.setAttribute('content', keywords);
// Update language meta tag
let metaLang = document.querySelector('meta[http-equiv="Content-Language"]');
if (!metaLang) {
metaLang = document.createElement('meta');
metaLang.setAttribute('http-equiv', 'Content-Language');
document.head.appendChild(metaLang);
}
metaLang.setAttribute('content', lang);
// Add hreflang tags for language alternatives
const supportedLangs = ['en', 'zh-CN', 'zh-TW', 'ko', 'ja'];
// Remove existing hreflang tags
document.querySelectorAll('link[rel="alternate"][hreflang]').forEach((el) => el.remove());
// Add new hreflang tags
const baseUrl = window.location.origin;
supportedLangs.forEach((supportedLang) => {
const hreflangLink = document.createElement('link');
hreflangLink.setAttribute('rel', 'alternate');
hreflangLink.setAttribute('hreflang', supportedLang);
hreflangLink.setAttribute('href', `${baseUrl}/${supportedLang}`);
document.head.appendChild(hreflangLink);
});
// Add x-default hreflang
const xDefaultLink = document.createElement('link');
xDefaultLink.setAttribute('rel', 'alternate');
xDefaultLink.setAttribute('hreflang', 'x-default');
xDefaultLink.setAttribute('href', `${baseUrl}/en`);
document.head.appendChild(xDefaultLink);
// Update canonical URL
let canonicalLink = document.querySelector('link[rel="canonical"]');
if (!canonicalLink) {
canonicalLink = document.createElement('link');
canonicalLink.setAttribute('rel', 'canonical');
document.head.appendChild(canonicalLink);
}
canonicalLink.setAttribute('href', window.location.href.split('?')[0]);
// Add Open Graph meta tags
let ogTitle = document.querySelector('meta[property="og:title"]');
if (!ogTitle) {
ogTitle = document.createElement('meta');
ogTitle.setAttribute('property', 'og:title');
document.head.appendChild(ogTitle);
}
ogTitle.setAttribute('content', title);
let ogDesc = document.querySelector('meta[property="og:description"]');
if (!ogDesc) {
ogDesc = document.createElement('meta');
ogDesc.setAttribute('property', 'og:description');
document.head.appendChild(ogDesc);
}
ogDesc.setAttribute('content', description);
let ogUrl = document.querySelector('meta[property="og:url"]');
if (!ogUrl) {
ogUrl = document.createElement('meta');
ogUrl.setAttribute('property', 'og:url');
document.head.appendChild(ogUrl);
}
ogUrl.setAttribute('content', window.location.href);
let ogType = document.querySelector('meta[property="og:type"]');
if (!ogType) {
ogType = document.createElement('meta');
ogType.setAttribute('property', 'og:type');
document.head.appendChild(ogType);
}
ogType.setAttribute('content', 'website');
// Add Twitter Card meta tags
let twitterCard = document.querySelector('meta[name="twitter:card"]');
if (!twitterCard) {
twitterCard = document.createElement('meta');
twitterCard.setAttribute('name', 'twitter:card');
document.head.appendChild(twitterCard);
}
twitterCard.setAttribute('content', 'summary_large_image');
let twitterTitle = document.querySelector('meta[name="twitter:title"]');
if (!twitterTitle) {
twitterTitle = document.createElement('meta');
twitterTitle.setAttribute('name', 'twitter:title');
document.head.appendChild(twitterTitle);
}
twitterTitle.setAttribute('content', title);
let twitterDesc = document.querySelector('meta[name="twitter:description"]');
if (!twitterDesc) {
twitterDesc = document.createElement('meta');
twitterDesc.setAttribute('name', 'twitter:description');
document.head.appendChild(twitterDesc);
}
twitterDesc.setAttribute('content', description);
}, [title, description, keywords, lang]);
// This component doesn't render anything visible
return null;
}