feat: add canonical URL handling and entity quality checks
- Implemented canonical URL strategies for city-specific domains and entities. - Added helper functions for domain and city resolution. - Created tests for canonical URL generation and domain resolution. - Introduced entity quality checks for doctors and clinics to ensure meaningful content. - Developed unique introductory texts for listing pages to avoid duplicate content. - Established robots.txt policies for listing pages to manage indexing based on user filters. - Enhanced specialty content with dynamic introductions and FAQs to improve SEO.
This commit is contained in:
@@ -0,0 +1,33 @@
|
||||
"use client";
|
||||
|
||||
import { useState } from "react";
|
||||
import ItemDoctor from "@/app/component/ItemDoctor";
|
||||
|
||||
// همان گرید و همان کارت پزشکِ /doctors — فقط بدون ماشین فیلتر، چون این صفحه
|
||||
// از قبل روی «تخصص + شهر» فیلتر شده و لیستش SSR میآید.
|
||||
function DoctorGrid({ doctors: initialDoctors = [] }) {
|
||||
const [doctors, setDoctors] = useState(initialDoctors);
|
||||
|
||||
if (!doctors.length) {
|
||||
return (
|
||||
<p className="text-center py-10 text-gray-500">
|
||||
دکتری برای نمایش وجود ندارد.
|
||||
</p>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<ul className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-[24px]">
|
||||
{doctors.map((doctor, idx) => (
|
||||
<ItemDoctor
|
||||
key={doctor.id}
|
||||
doctor={doctor}
|
||||
priority={idx < 3}
|
||||
setDoctors={setDoctors}
|
||||
/>
|
||||
))}
|
||||
</ul>
|
||||
);
|
||||
}
|
||||
|
||||
export default DoctorGrid;
|
||||
@@ -0,0 +1,30 @@
|
||||
// بلوک سوالات متداول — همان منبع دادهٔ FAQPage schema، تا متن دیدهشده و schema واگرا نشوند.
|
||||
// استایل با کارتهای موجود سایت همخانواده است (bg سفید، rounded-lg، border روشن).
|
||||
function Faq({ items = [] }) {
|
||||
if (!items.length) return null;
|
||||
|
||||
return (
|
||||
<section className="mt-[48px]">
|
||||
<h2 className="text-[#3B3B3B] text-[16px] sm:text-[19px] md:text-[22px] lg:text-[24px] font-bold mb-[24px]">
|
||||
سوالات متداول
|
||||
</h2>
|
||||
<div className="flex flex-col gap-[16px]">
|
||||
{items.map((item) => (
|
||||
<details
|
||||
key={item.question}
|
||||
className="p-4 rounded-lg bg-[#FFF] border border-[#EFEFEF]"
|
||||
>
|
||||
<summary className="text-[#3B3B3B] text-[16px] font-bold cursor-pointer">
|
||||
{item.question}
|
||||
</summary>
|
||||
<p className="text-[#525252] text-[14px] md:text-[16px] font-normal mt-[12px] leading-8">
|
||||
{item.answer}
|
||||
</p>
|
||||
</details>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
export default Faq;
|
||||
@@ -0,0 +1,36 @@
|
||||
import Pageguide from "@/app/component/Pageguide";
|
||||
import DoctorGrid from "./DoctorGrid";
|
||||
import Faq from "./Faq";
|
||||
|
||||
// چیدمان عمداً همخانوادهٔ /doctors است: همان padding-responsive، همان فاصلهٔ بالای صفحه،
|
||||
// همان تایپوگرافی عنوان و همان گرید کارت پزشک — کاربر نباید حس کند وارد بخش دیگری شده.
|
||||
function SpecialtyDetailPage({ specialtyName, cityName, doctors, intro, faq, origin }) {
|
||||
return (
|
||||
<div className="pt-[95px] sm:pt-[120px] padding-responsive">
|
||||
<Pageguide
|
||||
origin={origin}
|
||||
list={[
|
||||
{ name: "خانه", href: "/" },
|
||||
{ name: "تخصصها", href: "/specialties" },
|
||||
{ name: specialtyName },
|
||||
]}
|
||||
/>
|
||||
|
||||
<h1 className="text-[#3B3B3B] text-[16px] sm:text-[19px] md:text-[22px] lg:text-[24px] text-center font-bold mt-[24px]">
|
||||
متخصص {specialtyName} در {cityName}
|
||||
</h1>
|
||||
|
||||
<p className="text-[#525252] text-[14px] md:text-[16px] font-normal leading-8 mt-[16px] text-justify">
|
||||
{intro}
|
||||
</p>
|
||||
|
||||
<div className="mt-[24px] sm:mt-[37px] md:mt-[50px] lg:mt-[64px]">
|
||||
<DoctorGrid doctors={doctors} />
|
||||
</div>
|
||||
|
||||
<Faq items={faq} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default SpecialtyDetailPage;
|
||||
@@ -29,6 +29,7 @@ function SpecialtiesPage({ cityId, cityName, stateName }) {
|
||||
return (
|
||||
<>
|
||||
<HeadPageList
|
||||
titleTag="p"
|
||||
title="تخصص مورد نظر شما چیست؟"
|
||||
detail="تخصص مورد نظرتان را جستجو کرده و یا از لیست زیر انتخاب نمایید:"
|
||||
>
|
||||
|
||||
@@ -7,7 +7,7 @@ function List({ specialties = [], cityName, stateName }) {
|
||||
<div className="flex items-center justify-center gap-[12px] pt-[24px] mb-[40px]">
|
||||
<MenuS />
|
||||
<h1 className="text-[#3B3B3B] text-[16px] sm:text-[19px] md:text-[22px] lg:text-[24px] font-bold">
|
||||
لیست تخصص ها
|
||||
لیست تخصصهای پزشکی در {cityName || "ایران"}
|
||||
</h1>
|
||||
</div>
|
||||
{specialties.length === 0 ? (
|
||||
|
||||
Reference in New Issue
Block a user