Add SEO fields to city.json for local branding optimization
- Introduced a new `title` field for each city record, incorporating local brand names. - Rewrote `slogan` for each city to reflect startup tone and include city keywords. - Optimized `keywords` with relevant local and long-tail search terms. - Ensured compliance with SEO best practices and maintained JSON structure.
This commit is contained in:
@@ -0,0 +1,126 @@
|
||||
# بهینهسازی SEO فیلدهای city.json — افزودن title برنددار + بازنویسی slogan و keywords
|
||||
|
||||
## پروژه
|
||||
|
||||
`nobat724_front`
|
||||
|
||||
## زمینه
|
||||
|
||||
سایت چند-دامنهای است: هر شهر دامنه خودش را دارد (`tabriz-nobat.ir`، `esf-nobat.ir`، ...) و همه SEO هر شهر از `data/city.json` تغذیه میشود. `app/layout.js` در `generateMetadata` اول `matchedCity?.title` را میخواند و چون **هیچکدام از ۳۴ رکورد شهر فیلد `title` ندارند**، همیشه به الگوی fallback با برند سراسری «نوبت 724» میافتد — در حالی که هر شهر برند محلی خودش (`site_name` مثل «اراک نوبت») را دارد. `slogan` هم متن قابل ایندکس صفحات است (hero صفحه اصلی، about-us، پوستر پزشک) و باید هم مفهوم استارتآپی داشته باشد هم کلمه کلیدی شهر.
|
||||
|
||||
## مشکل / هدف
|
||||
|
||||
نقش: متخصص حرفهای SEO فارسی (local SEO سلامت/نوبتدهی پزشکی).
|
||||
|
||||
سه فیلد در هر ۳۴ رکورد `data/city.json` باید ساخته/بازنویسی شود:
|
||||
|
||||
1. **`title`** (فیلد جدید): عنوان متا برای هر شهر که **حتماً برند محلی (`site_name`) در آن باشد**. الگو:
|
||||
`نوبتدهی آنلاین پزشکان <name> | <site_name>`
|
||||
مثال هدف: `"title": "نوبتدهی آنلاین پزشکان اراک | اراک نوبت"`
|
||||
2. **`slogan`**: بازنویسی با مفهوم استارتآپی + SEO (کلمه کلیدی شهر داخلش باشد).
|
||||
3. **`keywords`**: بهینهسازی با کلمات کلیدی محلی و long-tail واقعی جستجوی فارسی.
|
||||
|
||||
## فایلهای مرتبط
|
||||
|
||||
| فایل | نقش |
|
||||
|------|-----|
|
||||
| `nobat724_front/data/city.json` | **تنها فایل قابل تغییر** — ۳۴ رکورد شهر |
|
||||
| `nobat724_front/app/layout.js` | مصرفکننده — فقط بخوان، تغییر نده |
|
||||
| `nobat724_front/components/home/TextHeader.js` | نمایش `slogan` در hero صفحه اصلی |
|
||||
| `nobat724_front/components/aboutUs/index.js` | نمایش `slogan` در about-us |
|
||||
| `nobat724_front/components/doctor/poster/index.js` | نمایش `slogan` در پوستر پزشک |
|
||||
|
||||
## وضعیت فعلی
|
||||
|
||||
`app/layout.js` (تغییر نمیکند — از قبل `title` را میخواند):
|
||||
|
||||
```js
|
||||
const title =
|
||||
matchedCity?.title ||
|
||||
(matchedCity?.name
|
||||
? `نوبتدهی آنلاین پزشکان ${matchedCity.name} | نوبت 724`
|
||||
: "نوبت 724 | سیستم نوبتدهی آنلاین پزشکی");
|
||||
```
|
||||
|
||||
نمونه رکورد فعلی `data/city.json` (فیلد `title` وجود ندارد):
|
||||
|
||||
```json
|
||||
{
|
||||
"id": 101,
|
||||
"name": "تبریز",
|
||||
"site_name": "تبریز نوبت",
|
||||
"description": "نوبت تبریز، سامانه تخصصی نوبتدهی پزشکی شمالغرب کشور است. ...",
|
||||
"slogan": "سریعترین نوبتدهی پزشکی تبریز",
|
||||
"domain": "tabriz-nobat.ir",
|
||||
"keywords": "نوبت تبریز, دکتر تبریز, پزشک متخصص تبریز, رزرو نوبت اینترنتی تبریز, کلینیک تبریز, بیمارستان تبریز, نوبت آنلاین آذربایجان شرقی",
|
||||
"province_id": 1
|
||||
}
|
||||
```
|
||||
|
||||
## وظایف
|
||||
|
||||
### ۱. افزودن فیلد `title` به هر ۳۴ رکورد
|
||||
|
||||
بعد از فیلد `site_name` (یا کنار فیلدهای SEO) در هر رکورد اضافه کن:
|
||||
|
||||
```json
|
||||
"title": "نوبتدهی آنلاین پزشکان تبریز | تبریز نوبت"
|
||||
```
|
||||
|
||||
قواعد:
|
||||
- الگوی ثابت: `نوبتدهی آنلاین پزشکان <name> | <site_name>` — کلمه کلیدی اصلی اول، برند آخر.
|
||||
- جداکننده ` | ` با فاصله در دو طرف (مثال کاربر فاصله نداشت — نسخه استاندارد با فاصله بنویس).
|
||||
- طول کل ≤ ۶۰ کاراکتر (برای عدم truncate در گوگل). همه نامهای شهر ایران در این الگو جا میشوند.
|
||||
- `name` و `site_name` را **دقیقاً از همان رکورد** بردار — دستساز ننویس (مثلاً اصفهان → «اصفهان نوبت»).
|
||||
- نیمفاصله در «نوبتدهی» حفظ شود ( = U+200C).
|
||||
|
||||
### ۲. بازنویسی `slogan` هر ۳۴ رکورد — استارتآپی + SEO
|
||||
|
||||
قواعد:
|
||||
- حتماً نام شهر + یکی از کلمات کلیدی (نوبت / پزشک / دکتر) داخل جمله باشد — این متن در H-level صفحه اصلی ایندکس میشود.
|
||||
- لحن استارتآپی: تمرکز بر سرعت، سادگی، دسترسی ۲۴ساعته، حذف صف — نه شعار خشک اداری.
|
||||
- کوتاه: ۴ تا ۸ کلمه؛ برای هر شهر **یکتا** (duplicate content بین ۳۴ دامنه ممنوع — گوگل دامنهها را جدا ایندکس میکند ولی الگوی تکراری ارزش برند را میکشد).
|
||||
- نمونههای جهتدهنده (کپی نکن، برای هر شهر متفاوت بساز):
|
||||
- «نوبت دکتر در تبریز، سادهتر از همیشه»
|
||||
- «پزشکان اصفهان، یک کلیک تا ویزیت»
|
||||
- «سلامت اهواز، بدون صف و انتظار»
|
||||
|
||||
### ۳. بهینهسازی `keywords` هر ۳۴ رکورد
|
||||
|
||||
قواعد:
|
||||
- ۷ تا ۱۰ عبارت، جدا با `, ` (فرمت فعلی حفظ شود — string، نه array).
|
||||
- ترکیب اجباری برای هر شهر:
|
||||
- `نوبت دکتر <شهر>` و `نوبتدهی آنلاین <شهر>` (پرجستجوترین الگوهای فارسی)
|
||||
- `دکتر خوب <شهر>` (الگوی long-tail رایج)
|
||||
- `پزشک متخصص <شهر>`
|
||||
- یک عبارت استانی (مثل `نوبت آنلاین آذربایجان شرقی`) از `state.json` با `province_id`
|
||||
- برند محلی: `<site_name>` (مثل `تبریز نوبت`)
|
||||
- عبارتهای کمارزش/تکراری فعلی (مثل `کلینیک <شهر>, بیمارستان <شهر>` خالی) را با long-tail هدفمند جایگزین کن: `رزرو نوبت پزشک <شهر>`، `نوبت اینترنتی دکتر <شهر>`.
|
||||
- keyword stuffing ممنوع — هر عبارت باید نیت جستجوی واقعی داشته باشد.
|
||||
|
||||
### ۴. اعتبارسنجی
|
||||
|
||||
```bash
|
||||
cd nobat724_front
|
||||
node -e "const d=require('./data/city.json'); \
|
||||
console.assert(d.length===34,'count'); \
|
||||
d.forEach(c=>{ \
|
||||
if(!c.title) throw new Error('no title: '+c.name); \
|
||||
if(!c.title.includes(c.site_name)) throw new Error('title missing site_name: '+c.name); \
|
||||
if(c.title.length>60) throw new Error('title too long: '+c.name); \
|
||||
if(!c.slogan.includes(c.name)&&!c.keywords.includes(c.name)) throw new Error('city name missing: '+c.name); \
|
||||
}); \
|
||||
const slogans=new Set(d.map(c=>c.slogan)); \
|
||||
console.assert(slogans.size===34,'duplicate slogans'); \
|
||||
console.log('OK')"
|
||||
npm run build # فقط اگر سریع بود؛ حداقل: node parse بالا باید OK بدهد
|
||||
```
|
||||
|
||||
## نکات مهم
|
||||
|
||||
- **فقط `data/city.json` تغییر میکند.** `app/layout.js` از قبل `matchedCity?.title` را میخواند؛ hero و about-us هم `slogan` را مستقیم نمایش میدهند — هیچ تغییر کدی لازم نیست.
|
||||
- ساختار JSON دست نخورد: هیچ فیلدی حذف/تغییرنام نشود، ترتیب رکوردها حفظ شود، encoding UTF-8 و نیمفاصلهها سالم بمانند.
|
||||
- `description` و `footer_description` در scope این پرامپت نیستند — ولی اگر با title/slogan جدید تناقض آشکار داشتند (مثلاً برند متفاوت)، فقط گزارش بده، تغییر نده.
|
||||
- نام استان هر شهر از `data/state.json` با `province_id` قابل استخراج است.
|
||||
- برای شهرهایی که `site_name` آنها با الگوی `<شهر> نوبت` نیست، همان مقدار واقعی فایل ملاک است.
|
||||
- زبان همه مقادیر: فارسی (محصول تماماً فارسی/RTL است).
|
||||
Reference in New Issue
Block a user