feat(breadcrumb): implement BreadcrumbList structure and validation for SEO compliance

This commit is contained in:
hamed
2026-07-24 10:39:41 +03:30
parent 9053681375
commit b8514e64cf
11 changed files with 178 additions and 30 deletions
+2 -1
View File
@@ -29,7 +29,8 @@ function ClinicPage({ data, doctors, slug, pages, origin }) {
list={[
{ name: "خانه", href: "/" },
{ name: "کلینیک ها", href: "/clinics" },
{ name: data?.title },
// href صفحهٔ جاری لازم است تا `item` در BreadcrumbList خالی نماند
{ name: data?.title, href: slug ? `/clinic/${slug}` : "/clinics" },
]}
/>
</div>
+2 -1
View File
@@ -14,7 +14,7 @@ import cities from "@/data/city.json";
import { isRootCity } from "@/lib/rootCity";
import { resolveCityDisplayName } from "@/lib/domainHelpers";
function ClinicsPage({ clinics, matchedCity, matchedState }) {
function ClinicsPage({ clinics, matchedCity, matchedState, origin }) {
const searchParams = useSearchParams();
const [page, setPage] = useState(clinics?.meta?.currentPage || 1);
const [filteredClinics, setFilteredClinics] = useState(clinics?.data);
@@ -52,6 +52,7 @@ function ClinicsPage({ clinics, matchedCity, matchedState }) {
<List
limit={12}
page={page}
origin={origin}
setPage={setPage}
selected={selected}
clinics={filteredClinics}
+5 -2
View File
@@ -10,15 +10,18 @@ function List({
page,
limit,
pages,
origin,
setPage,
clinics,
selected,
setFilteredClinics,
}) {
// آیتم آخر هم href می‌گیرد: بدون آن، `item` در BreadcrumbList غایب می‌شود و
// سرچ‌کنسول کل breadcrumb صفحه را نامعتبر اعلام می‌کند.
const listPage = [
{ name: "خانه", href: "/" },
{ name: "کلینیک ها", href: "/clinics" },
{ name: selected?.city?.name || "" },
{ name: selected?.city?.name || "", href: "/clinics" },
];
const [loading, setLoading] = useState(false);
const router = useRouter();
@@ -48,7 +51,7 @@ function List({
return (
<div className="padding-responsive pt-[20px]">
<Pageguide list={listPage} />
<Pageguide list={listPage} origin={origin} />
{clinics && clinics.length ? (
<ul
className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-x-[24px] gap-y-[16px] sm:gap-y-[24px] md:gap-y-[32px] lg:gap-y-[40px] mt-6"
+3 -2
View File
@@ -4,7 +4,7 @@ import Faq from "./Faq";
// چیدمان عمداً هم‌خانوادهٔ /doctors است: همان padding-responsive، همان فاصلهٔ بالای صفحه،
// همان تایپوگرافی عنوان و همان گرید کارت پزشک — کاربر نباید حس کند وارد بخش دیگری شده.
function SpecialtyDetailPage({ specialtyName, cityName, doctors, intro, faq, origin }) {
function SpecialtyDetailPage({ specialtyName, cityName, doctors, intro, faq, origin, slug }) {
return (
<div className="pt-[95px] sm:pt-[120px] padding-responsive">
<Pageguide
@@ -12,7 +12,8 @@ function SpecialtyDetailPage({ specialtyName, cityName, doctors, intro, faq, ori
list={[
{ name: "خانه", href: "/" },
{ name: "تخصص‌ها", href: "/specialties" },
{ name: specialtyName },
// href صفحهٔ جاری: بدون آن `item` غایب می‌شود و اسکیما نامعتبر است
{ name: specialtyName, href: slug ? `/specialties/${slug}` : "/specialties" },
]}
/>