Files
nobat724_front/.claude/prompt/city-seo-optimization.md
T

179 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# بهینه‌سازی SEO تک‌تک شهرها در city.json (سطح حرفه‌ای)
## پروژه
`nobat724_front` (سایت عمومی نوبت‌دهی، چند-دامنه‌ای — هر شهر یک دامنه)
## نقش
تو یک **متخصص حرفه‌ای SEO فارسی/محلی (Local SEO)** هستی. خروجی باید در سطح یک آژانس سئوی حرفه‌ای باشد: یکتا، کلیدواژه‌محور بدون stuffing، با رعایت طول بهینه، CTR-optimized.
## زمینه
`data/city.json` منبع واحد SEO هر دامنه‌ی شهری است. `app/layout.js``generateMetadata()` مقادیر این فایل را مستقیم به تگ‌های متا تبدیل می‌کند. یعنی کیفیت SEO هر شهر = کیفیت فیلدهای متنی همان رکورد در این فایل.
۳۴ رکورد وجود دارد (۳۳ شهر + رکورد اصلی `id:600` دامنه `nobat724.com`). محتوای فعلی با یک **قالب یکسان کلون** شده — جملات تقریباً تکراری بین شهرها (خطر duplicate content) و ضعیف.
## مشکل / هدف
دو مشکل بحرانی:
1. **فیلد `title` در هیچ‌کدام از ۳۴ رکورد وجود ندارد.** `layout.js` اول `matchedCity?.title` را می‌خواند؛ چون نیست، همه شهرها به یک قالب یکسان fallback می‌کنند → تایتل‌های تقریباً تکراری. **باید به هر رکورد فیلد `title` یکتا و بهینه اضافه شود.**
2. `description` / `keywords` / `slogan` / `footer_description` قالبی و تکراری‌اند → باید هرکدام برای هر شهر **بازنویسی یکتا و بهینه** شوند.
هدف: هر ۳۴ رکورد، ۵ فیلد متنی SEO در بالاترین کیفیت، **بدون تکرار جمله بین شهرها**.
## فایل‌های مرتبط
| فایل | نقش |
|------|-----|
| `data/city.json` | تنها فایلی که ویرایش می‌شود — رکورد هر شهر |
| `app/layout.js` | مصرف‌کننده فیلدها (فقط برای درک، ویرایش نشود مگر task ۶) |
## وضعیت فعلی
مصرف فیلدها در `app/layout.js`:
```js
const title =
matchedCity?.title || // ← این فیلد وجود ندارد!
(matchedCity?.name
? `نوبت‌دهی آنلاین پزشکان ${matchedCity.name} | نوبت 724`
: "نوبت 724 | سیستم نوبت‌دهی آنلاین پزشکی");
const description = matchedCity?.description || "...";
// keywords: matchedCity.keywords
// openGraph.siteName: matchedCity.site_name
```
نمونه رکورد فعلی (تکراری/قالبی):
```json
{
"id": 113, "name": "اهواز", "site_name": "اهواز نوبت",
"province_name": "خوزستان",
"description": "اهواز نوبت، سامانه نوبت‌دهی آنلاین در اهواز و استان خوزستان. امکان جستجو و رزرو نوبت در مراکز درمانی. اهواز نوبت بهترین راه دسترسی به پزشکان متخصص است.",
"slogan": "سامانه هوشمند نوبت‌دهی پزشکان اهواز",
"keywords": "رزرو نوبت اهواز, پزشکان خوزستان, کلینیک‌های اهواز, بیمارستان‌های اهواز, متخصصین پزشکی اهواز",
"footer_description": "اهواز نوبت، سامانه جامع نوبت‌دهی پزشکی در استان خوزستان. رزرو نوبت از پزشکان و مراکز درمانی اهواز بدون نیاز به مراجعه حضوری."
}
```
## فهرست ۳۴ رکورد (همه باید پردازش شوند)
| id | شهر | استان | دامنه |
|----|-----|-------|-------|
| 129 | اراک | مرکزی | arak-nobat.ir |
| 103 | اردبیل | اردبیل | ardabil-nobat.ir |
| 102 | ارومیه | آذربایجان غربی | urmia-nobat.ir |
| 104 | اصفهان | اصفهان | esf-nobat.ir |
| 113 | اهواز | خوزستان | ahvaz-nobat.ir |
| 106 | ایلام | ایلام | ilam-nobat.ir |
| 112 | بجنورد | خراسان شمالی | bojnord-nobat.ir |
| 130 | بندرعباس | هرمزگان | bandar-nobat.ir |
| 107 | بوشهر | بوشهر | bushehr-nobat.ir |
| 110 | بیرجند | خراسان جنوبی | birjand-nobat.ir |
| 101 | تبریز | آذربایجان شرقی | tabriz-nobat.ir |
| 108 | تهران | تهران | tehran-nobat.ir |
| 127 | خرم‌آباد | لرستان | lorestan-nobat.ir |
| 126 | رشت | گیلان | rasht-nobat.ir |
| 116 | زاهدان | سیستان و بلوچستان | zahedan-nobat.ir |
| 114 | زنجان | زنجان | zanjan-nobat.ir |
| 128 | ساری | مازندران | sari-nobat.ir |
| 115 | سمنان | سمنان | semnan-nobat.ir |
| 120 | سنندج | کردستان | sanandaj-nobat.ir |
| 109 | شهرکرد | چهارمحال و بختیاری | shkord-nobat.ir |
| 117 | شیراز | فارس | shiraz-nobat.ir |
| 118 | قزوین | قزوین | qazvin-nobat.ir |
| 119 | قم | قم | qom-nobat.ir |
| 105 | کرج | البرز | karaj-nobat.ir |
| 121 | کرمان | کرمان | kerman-nobat.ir |
| 122 | کرمانشاه | کرمانشاه | kermanshah-nobat.ir |
| 125 | گرگان | گلستان | golestan-nobat.ir |
| 111 | مشهد | خراسان رضوی | mashhad-nobat.ir |
| 131 | همدان | همدان | hamadan-nobat.ir |
| 123 | یاسوج | کهگیلویه و بویراحمد | yasuj-nobat.ir |
| 132 | یزد | یزد | yazd-nobat.ir |
| 133 | دهدشت | کهگیلویه و بویراحمد | dehdasht-nobat.ir |
| 134 | بهبهان | خوزستان | behbahan-nobat.ir |
| 600 | نوبت 724 (برند اصلی) | — | nobat724.com |
## وظایف
### ۱. افزودن فیلد `title` یکتا به هر رکورد (مهم‌ترین)
بعد از `site_name` در هر رکورد، فیلد `title` اضافه کن.
**قواعد `title`:**
- طول: **۵۰–۶۰ کاراکتر** (حداکثر ~۶۰ برای عدم truncate در گوگل).
- کلیدواژه اصلی **اول** جمله: «نوبت‌دهی آنلاین پزشکان {شهر}» یا واریانت.
- برند در انتها با جداکننده `|`: `... | نوبت ۷۲۴`.
- **یکتا بین شهرها** — فقط جای‌گذاری اسم شهر کافی نیست؛ ساختار/کلمات را بین گروه‌ها متنوع کن (مثلاً برخی «رزرو نوبت پزشک {شهر}»، برخی «نوبت اینترنتی دکتر {شهر}»).
- بدون stuffing، خوانا، طبیعی.
مثال طلایی:
```json
"title": "نوبت‌دهی آنلاین پزشکان اهواز | رزرو نوبت دکتر | نوبت ۷۲۴"
```
### ۲. بازنویسی `description` (متا دیسکریپشن)
**قواعد:**
- طول: **۱۵۰–۱۶۰ کاراکتر** (نه کمتر از ۱۲۰، نه بیشتر از ۱۶۵).
- کلیدواژه اصلی front-load شده در ابتدای جمله.
- شامل: نام شهر + استان + اشاره به تخصص‌ها/مراکز درمانی + **CTA** («همین حالا رزرو کنید» / «آنلاین نوبت بگیرید»).
- **یکتا** — هیچ دو شهری جمله‌ی یکسان نداشته باشند. زاویه‌ی متن را متنوع کن (یکی روی سرعت، یکی روی تنوع پزشکان، یکی روی ۲۴ساعته‌بودن).
- بدون تکرار بیش از حد اسم شهر (حداکثر ۲ بار).
مثال طلایی:
```json
"description": "با نوبت اهواز، آنلاین از پزشکان متخصص و عمومی خوزستان نوبت بگیرید. جستجوی دکتر بر اساس تخصص، بیمه و منطقه در اهواز؛ رزرو نوبت ۲۴ساعته بدون مراجعه حضوری. همین حالا نوبت خود را ثبت کنید."
```
### ۳. بهینه‌سازی `keywords`
- ۶–۹ عبارت هدفمند، جدا با `, `.
- ترکیب: `نوبت {شهر}`، `دکتر {شهر}`، `پزشک متخصص {شهر}`، `رزرو نوبت اینترنتی {شهر}`، `کلینیک {شهر}`، `بهترین پزشک {استان}`، عبارات intent-محور («نوبت آنلاین دکتر»).
- بدون تکرار عین‌به‌عین عبارات بین شهرها (اسم شهر متفاوت کافی نیست برای long-tailها).
### ۴. بازنویسی `slogan` یکتا
- کوتاه (۴–۸ کلمه)، جذاب، دارای کلیدواژه شهر، متمایز بین شهرها.
- نمونه: `"در اهواز، نوبت دکتر فقط با چند کلیک"`.
### ۵. بازنویسی `footer_description` یکتا
- ۱–۲ جمله، محلی، دارای شهر+استان، متفاوت از `description` (نه کپی).
- برای فوتر — لحن معرفی برند محلی.
### ۶. (اختیاری، اگر کاربر خواست) بهبود فنی در `layout.js`
اگر زمان بود، این‌ها را هم پیشنهاد بده (اما JSON اولویت است):
- `openGraph.images` و `twitter.images` الان هاردکد `nobat724.com/assets/images/logo.png` است — می‌توان per-city کرد.
- JSON-LD فعلی فقط `Organization` + `WebSite` با `siteUrl` ثابت `nobat724.com` است؛ افزودن `MedicalBusiness`/`LocalBusiness` per-city با دامنه و نام شهر، سیگنال Local SEO قوی می‌دهد.
### ۷. رکورد برند اصلی (`id: 600`)
این رکورد شهر نیست (دامنه‌ی مادر `nobat724.com`, `province_name: null`). برایش `title`/`description`/`keywords` سراسری و برندمحور بنویس (نه شهرمحور): تمرکز روی «سامانه سراسری نوبت‌دهی آنلاین پزشکی ایران».
## نکات مهم
- **فقط `data/city.json` ویرایش شود** (به‌جز task ۶ اختیاری). ساختار JSON، ترتیب رکوردها، و فیلدهای `id`, `uuid`, `status`, `weight`, `province_id`, `province_name`, `representation_id`, `contact_phone`, `email`, `domain`, `social_media`, `logo_url` **دست‌نخورده** بمانند.
- فیلد `title` جدید را بعد از `site_name` قرار بده (سازگاری با ترتیب منطقی).
- **اعداد در `title` فارسی** باشند (`۷۲۴` نه `724`) برای هماهنگی با UI فارسی — مگر اینکه در برند لاتین لازم باشد.
- **یکتایی سراسری**: بعد از اتمام، هیچ دو رکوردی نباید `title` یا `description` با ساختار جمله‌ی یکسان (فقط تغییر اسم شهر) داشته باشند. حداقل ۳–۴ الگوی متنی متفاوت بین ۳۴ رکورد بچرخان.
- **صحت جغرافیایی**: `province_name` هر رکورد را به‌عنوان واقعیت بپذیر (قبلاً بهبهان=خوزستان، دهدشت=کهگیلویه اصلاح شده). محتوای استان را با همین مقدار بنویس.
- بعد از ویرایش، **اعتبار JSON را تأیید کن**:
```bash
python3 -c "import json; d=json.load(open('data/city.json')); print('valid', len(d)); \
t=[c.get('title') for c in d]; assert all(t), 'missing title'; \
print('unique titles:', len(set(t))==len(t)); \
print('unique descriptions:', len(set(c['description'] for c in d))==len(d))"
```
باید: valid، همه title دارند، titleها و descriptionها یکتا.
- زبان فارسی رسمی و روان، RTL، بدون غلط املایی. اسامی شهر/استان دقیقاً مطابق فایل.
- این تغییر داده است، نه endpoint API → نیازی به به‌روزرسانی `docs/api/` نیست.
- بعد از ویرایش، یک build سریع بزن که فایل درست پارس می‌شود: `npm run build` (یا حداقل import شدن JSON).
```