# بهینه‌سازی 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`) در آن باشد**. الگو: `نوبت‌دهی آنلاین پزشکان | ` مثال هدف: `"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": "نوبت‌دهی آنلاین پزشکان تبریز | تبریز نوبت" ``` قواعد: - الگوی ثابت: `نوبت‌دهی آنلاین پزشکان | ` — کلمه کلیدی اصلی اول، برند آخر. - جداکننده ` | ` با فاصله در دو طرف (مثال کاربر فاصله نداشت — نسخه استاندارد با فاصله بنویس). - طول کل ≤ ۶۰ کاراکتر (برای عدم truncate در گوگل). همه نام‌های شهر ایران در این الگو جا می‌شوند. - `name` و `site_name` را **دقیقاً از همان رکورد** بردار — دست‌ساز ننویس (مثلاً اصفهان → «اصفهان نوبت»). - نیم‌فاصله در «نوبت‌دهی» حفظ شود (‌ = U+200C). ### ۲. بازنویسی `slogan` هر ۳۴ رکورد — استارت‌آپی + SEO قواعد: - حتماً نام شهر + یکی از کلمات کلیدی (نوبت / پزشک / دکتر) داخل جمله باشد — این متن در H-level صفحه اصلی ایندکس می‌شود. - لحن استارت‌آپی: تمرکز بر سرعت، سادگی، دسترسی ۲۴ساعته، حذف صف — نه شعار خشک اداری. - کوتاه: ۴ تا ۸ کلمه؛ برای هر شهر **یکتا** (duplicate content بین ۳۴ دامنه ممنوع — گوگل دامنه‌ها را جدا ایندکس می‌کند ولی الگوی تکراری ارزش برند را می‌کشد). - نمونه‌های جهت‌دهنده (کپی نکن، برای هر شهر متفاوت بساز): - «نوبت دکتر در تبریز، ساده‌تر از همیشه» - «پزشکان اصفهان، یک کلیک تا ویزیت» - «سلامت اهواز، بدون صف و انتظار» ### ۳. بهینه‌سازی `keywords` هر ۳۴ رکورد قواعد: - ۷ تا ۱۰ عبارت، جدا با `, ` (فرمت فعلی حفظ شود — string، نه array). - ترکیب اجباری برای هر شهر: - `نوبت دکتر <شهر>` و `نوبت‌دهی آنلاین <شهر>` (پرجستجوترین الگوهای فارسی) - `دکتر خوب <شهر>` (الگوی long-tail رایج) - `پزشک متخصص <شهر>` - یک عبارت استانی (مثل `نوبت آنلاین آذربایجان شرقی`) از `state.json` با `province_id` - برند محلی: `` (مثل `تبریز نوبت`) - عبارت‌های کم‌ارزش/تکراری فعلی (مثل `کلینیک <شهر>, بیمارستان <شهر>` خالی) را با 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 است).