feat: رفع لینک /doctor/undefined و متمایزسازی صفحهٔ اصلی شهرها
- ایجاد پرامپت برای رفع خطای 404 ناشی از لینک `/doctor/undefined` در سایتهای بهبهان و یاسوج. - افزودن کامپوننت `CityHighlights` برای نمایش محتوای یکتا و آمار پزشکان و تخصصهای پرمراجعه در صفحهٔ اصلی هر شهر. - بهروزرسانی تستهای مربوط به کامپوننتهای `ItemDoctor` و `CityHighlights` برای اطمینان از عدم وجود لینکهای نامعتبر و نمایش صحیح اطلاعات. - ایجاد سند جدید برای مستندسازی خطاهای Search Console که باگ نیستند و نیاز به رفع ندارند. - افزودن تستهای واحد برای توابع `buildCityIntro` و دیگر توابع مرتبط با تولید متن یکتا برای صفحات لیست.
This commit is contained in:
@@ -0,0 +1,154 @@
|
||||
# خطاهای Search Console که باگ نیستند
|
||||
|
||||
هر دامنهٔ شهری در Google Search Console چند دستهٔ «مشکل» نشان میدهد که خروجیِ **تصمیمهای
|
||||
عمدی** سیستماند، نه نقص. این سند مرجع است تا هر بار کسی داشبورد را باز کرد، دوباره دنبال
|
||||
رفع چیزی نگردد که نباید رفع شود.
|
||||
|
||||
سنجشهای این سند روی `behbahan-nobat.ir` و `yasuj-nobat.ir` در ۵ اوت ۲۰۲۶ گرفته شدهاند.
|
||||
|
||||
> آنچه **واقعاً** باگ بود و جدا رفع میشود، اینجا نیست:
|
||||
> `/doctor/undefined` و یکسانبودن صفحهٔ اصلی شهرها.
|
||||
> ← `.claude/prompt/gsc-undefined-link-and-home-uniqueness.md`
|
||||
|
||||
---
|
||||
|
||||
## ۱. Excluded by 'noindex' tag
|
||||
|
||||
**نمونه:** ۸۰ صفحه در یاسوج، ۱۲ صفحه در بهبهان — عمدتاً `/doctor/<uuid>`.
|
||||
|
||||
**چرا عمدی است**
|
||||
|
||||
پروفایل پزشکی که از نظام پزشکی وارد شده و خودِ پزشک آن را claim نکرده، محتوای قابل
|
||||
اتکا نیست. `lib/entityQuality.js` همین را اعمال میکند:
|
||||
|
||||
```js
|
||||
export function isUnclaimedDoctor(doctor) {
|
||||
return doctor?.owner_status !== "claimed";
|
||||
}
|
||||
|
||||
export function isNoindexDoctor(doctor) {
|
||||
return isThinDoctor(doctor) || isUnclaimedDoctor(doctor);
|
||||
}
|
||||
```
|
||||
|
||||
همین تابع هم `robots` صفحهٔ پزشک را میسازد و هم ورودی `app/sitemap.js` را فیلتر میکند، تا
|
||||
چیزی که noindex است هرگز در sitemap اعلام نشود.
|
||||
|
||||
پزشک «بیمحتوا» هم noindex میشود: بدون نام واقعی (شمارهٔ تلفن یا «تست» بهجای نام)، یا
|
||||
بدون هیچ تخصص و مکانی.
|
||||
|
||||
**چه چیزی این را برمیدارد**
|
||||
|
||||
فقط claim شدن پروفایل توسط خودِ پزشک، یا کامل شدن نام و تخصص و مکان. **هیچ تغییر کدی
|
||||
لازم نیست و هیچ تغییر کدی هم نباید انجام شود.**
|
||||
|
||||
**چرا `VALIDATE FIX` شکست میخورد**
|
||||
|
||||
در یاسوج این اعتبارسنجی روی ۲۸ ژوئیه شروع و ۵ اوت `Validation failed` شد. طبیعی است:
|
||||
اعتبارسنجی یعنی «به گوگل بگو دیگر noindex نیست» در حالی که صفحات عمداً noindex ماندهاند.
|
||||
**این دکمه را برای این دسته نزنید.** هر بار شکست میخورد و فقط تاریخچهٔ داشبورد را شلوغ میکند.
|
||||
|
||||
---
|
||||
|
||||
## ۲. Alternate page with proper canonical tag
|
||||
|
||||
**نمونه در بهبهان:** `/about-us`، `/contact-us`، و دو `/clinic/<uuid>`.
|
||||
|
||||
**چرا عمدی است**
|
||||
|
||||
استراتژی canonical سهدسته است و در بالای `lib/getCanonicalUrl.js` مستند شده:
|
||||
|
||||
| دسته | مسیرها | canonical |
|
||||
|---|---|---|
|
||||
| C1-a | `/`، `/doctors`، `/clinics`، `/specialties`، `/blogs` | self روی همان دامنهٔ شهری |
|
||||
| C1-b | `/doctor/[uuid]`، `/clinic/[uuid]`، `/blog/[slug]` | دامنهٔ شهرِ خودِ موجودیت |
|
||||
| C1-c | `/about-us`، `/contact-us`، `/terms`، `/privacy` | دامنهٔ اصلی `nobat724.com` |
|
||||
|
||||
`/about-us` و `/contact-us` روی همهٔ دامنهها محتوای یکسان دارند، پس اعتبارشان عمداً روی
|
||||
دامنهٔ اصلی تجمیع میشود. کلینیکی هم که شهرش بهبهان نیست، canonicalاش به دامنهٔ شهر خودش
|
||||
میرود تا یک موجودیت روی دو دامنه دو صفحهٔ رقیب نسازد.
|
||||
|
||||
`Alternate page with proper canonical tag` در Search Console **گزارش اطلاعاتی** است، نه خطا.
|
||||
عبارت `proper` در عنوانش یعنی گوگل canonical ما را پذیرفته. این دقیقاً نتیجهٔ مطلوب است.
|
||||
|
||||
---
|
||||
|
||||
## ۳. Page with redirect
|
||||
|
||||
**نمونه:** `http://behbahan-nobat.ir/` — یک صفحه.
|
||||
|
||||
ریدایرکت `http` به `https` است. رفتار درست و لازم. کاری ندارد.
|
||||
|
||||
---
|
||||
|
||||
## ۴. آدرسهای قدیمی بلاگ که ۴۰۴ میدهند
|
||||
|
||||
**نمونه در بهبهان:** چهار آدرس با slug انگلیسی، مثل
|
||||
`/blog/warning-signs-sleep-elderly` و `/blog/alamat-tahooe-mokarrar-dar-bimaran-sartani`.
|
||||
|
||||
**چه اتفاقی افتاده**
|
||||
|
||||
فرمت slug مقالهها عوض شده. slug امروز فارسی است با پسوند هگز هشتکاراکتری — نمونهٔ
|
||||
واقعی از API:
|
||||
|
||||
```
|
||||
آلرژی-دارویی-تشخیص-علائم-خطرناک-و-ضرورت-مراجعه-به-پزشک-58d2e880
|
||||
```
|
||||
|
||||
slugهای انگلیسیِ قبلی دیگر وجود ندارند و **نگاشت قدیمبهجدید هیچجا ذخیره نشده**.
|
||||
|
||||
**تصمیم: ۴۰۴ پذیرفته میشود**
|
||||
|
||||
۴۰۴ پاسخ صحیح برای محتوایی است که دیگر با آن نشانی وجود ندارد. گوگل خودش این آدرسها را
|
||||
از ایندکس حذف میکند. ساختن redirect نیازمند پیدا کردن دستیِ معادل هر کدام است و فقط
|
||||
چهار آدرس در میان است.
|
||||
|
||||
بررسی شد که خودِ رفتار ۴۰۴ سالم است — سه نشانیِ ناموجود، هر سه `404`:
|
||||
|
||||
```
|
||||
/blog/warning-signs-sleep-elderly → 404
|
||||
/blog/definitely-does-not-exist-xyz-123 → 404
|
||||
/blog/alamat-tahooe-mokarrar-dar-bimaran-sartani → 404
|
||||
```
|
||||
|
||||
**اگر روزی slug دوباره عوض شد**, اینبار قبلش نگاشت را نگه دارید. تکرار همین وضعیت با
|
||||
تعداد بیشتر، دیگر با «۴۰۴ بپذیر» حل نمیشود.
|
||||
|
||||
---
|
||||
|
||||
## ۵. Discovered — currently not indexed
|
||||
|
||||
**نمونه:** ۷۳ آدرس در یاسوج — صفحات تخصص، کلینیک، پزشک و بلاگ.
|
||||
|
||||
**معنایش**
|
||||
|
||||
گوگل این آدرسها را پیدا کرده اما هنوز crawl نکرده. تقریباً همیشه یعنی سایت در نظر گوگل
|
||||
اولویت crawl پایینی دارد، نه اینکه صفحه خراب باشد.
|
||||
|
||||
**چرا اینجا رخ میدهد**
|
||||
|
||||
دو عامل، و هر دو در حال رفعاند یا عمدیاند:
|
||||
|
||||
۱. سهم بزرگی از صفحات دامنه noindex است (بند ۱). سایتی که بیشتر صفحاتش noindex است،
|
||||
سیگنال ضعیفتری برای صرف بودجهٔ crawl میدهد.
|
||||
۲. صفحهٔ اصلی شهرها تا پیش از این ۹۹٪ شبیه هم بود. این مورد **باگ است** و جدا رفع میشود
|
||||
(پرامپت بالای این سند).
|
||||
|
||||
**کاری که نباید کرد**
|
||||
|
||||
آدرسها را دستی و دستهای برای ایندکس submit نکنید. مشکل کمبودِ کشف نیست؛ اعلام دوبارهٔ
|
||||
همان آدرسها چیزی را جلو نمیاندازد.
|
||||
|
||||
---
|
||||
|
||||
## خلاصهٔ تصمیم
|
||||
|
||||
| دستهٔ Search Console | وضعیت | اقدام |
|
||||
|---|---|---|
|
||||
| Excluded by 'noindex' tag | عمدی | هیچ. `Validate fix` نزنید |
|
||||
| Alternate page with proper canonical | عمدی و مطلوب | هیچ |
|
||||
| Page with redirect | طبیعی | هیچ |
|
||||
| Not found (404) — بلاگهای قدیمی | پذیرفتهشده | هیچ |
|
||||
| Not found (404) — `/doctor/undefined` | **باگ** | پرامپت جداگانه |
|
||||
| Duplicate, Google chose different canonical | **باگ محتوایی** | پرامپت جداگانه |
|
||||
| Discovered — currently not indexed | پیامد دو مورد بالا | بعد از رفع آنها دوباره سنجیده شود |
|
||||
Reference in New Issue
Block a user