- پنل «بررسی سئو» در صفحه نوشتن مقاله — سبز/نارنجی/قرمز سازگار با فارسی: طول عنوان، کلمه کلیدی هدف (در عنوان/پاراگراف اول/تیتر H2)، طول چکیده، تعداد واژه، تیتربندی، متن جایگزین تصاویر، پیوندها و slug. کلمه کلیدی در localStorage نگه داشته میشود (راهنمای ویرایشگر است، نه محتوا) - جدول seo_meta: عنوان و توضیح متای هر صفحه (page_key برای هر ۸ صفحه، seed خودکار، CRUD در /api/admin/seo-meta، خواندن در GET /api/site) - تزریق عنوان/توضیح متا در فرانتاند: صفحههای فهرست از دیتابیس؛ صفحه مقاله و پروژه از محتوای خودشان (بدون تداخل با اثر سطح والد) - دکمه سئو روی هیرو هر صفحه و کنار هیرو صفحه اصلی (فقط حالت ویرایش)
25 lines
1.1 KiB
TypeScript
25 lines
1.1 KiB
TypeScript
// تنظیم عنوان صفحه و توضیح متا — محتوای سئو از دیتابیس میآید
|
|
|
|
export function setMetaDescription(content: string): void {
|
|
let el = document.querySelector<HTMLMetaElement>('meta[name="description"]')
|
|
if (!content.trim()) {
|
|
el?.remove()
|
|
return
|
|
}
|
|
if (!el) {
|
|
el = document.createElement('meta')
|
|
el.setAttribute('name', 'description')
|
|
document.head.appendChild(el)
|
|
}
|
|
el.setAttribute('content', content.trim())
|
|
}
|
|
|
|
/** کلید سئوی مسیر جاری — فقط صفحههای فهرست دقیق؛ صفحههای جزئیات خودشان عنوان میگذارند */
|
|
export function seoKeyForPath(pathname: string): string | null {
|
|
if (pathname === '/') return 'home'
|
|
const seg = pathname.split('/')[1] ?? ''
|
|
const known = ['about', 'services', 'projects', 'investment', 'blog', 'faq', 'contact']
|
|
// مسیرهای جزئی مثل /blog/{slug} شامل نمیشوند تا اثر خود صفحه جزئیات برسانند
|
|
return known.includes(seg) && pathname === `/${seg}` ? seg : null
|
|
}
|