feat: add doctorTitle helper function and update references in metadata and FAQ

This commit is contained in:
hamed
2026-07-19 15:40:24 +03:30
parent b3ffba82d4
commit 4c8377f439
3 changed files with 16 additions and 7 deletions
+6 -6
View File
@@ -9,7 +9,7 @@ import { buildDoctorFaq } from "@/lib/specialtyContent";
import { isThinDoctor } from "@/lib/entityQuality";
import specialtiesData from "@/data/specialties.json";
import { safeJsonLd } from "@/lib/sanitize";
import { imageUrl } from "@/helper";
import { imageUrl, doctorTitle } from "@/helper";
const API_URL = process.env.NEXT_PUBLIC_API_URL;
const FALLBACK_IMG = "/assets/images/og-image.png";
@@ -71,14 +71,14 @@ export async function generateMetadata({ params }) {
try {
const specialtyNames = doctor.specialties?.map((s) => s.name).join(" و ") || "";
const title = `دکتر ${doctor.name}${specialtyNames ? " | " + specialtyNames : ""} | ${siteName}`;
const title = `${doctorTitle(doctor.name)}${specialtyNames ? " | " + specialtyNames : ""} | ${siteName}`;
const detailText = (doctor.detail || "")
.replace(/<[^>]*>/g, "")
.replace(/\s+/g, " ")
.trim();
const description = (
detailText ||
`رزرو نوبت آنلاین دکتر ${doctor.name}${specialtyNames ? " متخصص " + specialtyNames : ""}${doctor.address ? " | " + doctor.address : ""}`.trim()
`رزرو نوبت آنلاین ${doctorTitle(doctor.name)}${specialtyNames ? " متخصص " + specialtyNames : ""}${doctor.address ? " | " + doctor.address : ""}`.trim()
).slice(0, 160);
const image = imageUrl(doctor.img?.[0]?.url) || FALLBACK_IMG;
// C1-b — پزشک به دامنهٔ شهر خودش canonical می‌شود، روی هر دامنه‌ای که سرو شود.
@@ -172,7 +172,7 @@ async function Doctor({ params }) {
"@context": "https://schema.org",
"@type": "Physician",
"@id": `${origin}/doctor/${doctor.uuid}#physician`,
name: `دکتر ${doctor.name}`,
name: doctorTitle(doctor.name),
url: `${origin}/doctor/${doctor.uuid}`,
...(specialtyNames && { medicalSpecialty: specialtyNames }),
...(doctor.img?.[0]?.url && {
@@ -212,7 +212,7 @@ async function Doctor({ params }) {
...(bookableAddresses.length > 0 && {
workLocation: bookableAddresses.map((addr) => ({
"@type": "MedicalClinic",
name: addr.clinic_name || addr.name || `مطب دکتر ${doctor.name}`,
name: addr.clinic_name || addr.name || `مطب ${doctorTitle(doctor.name)}`,
address: {
"@type": "PostalAddress",
streetAddress: addr.address,
@@ -254,7 +254,7 @@ async function Doctor({ params }) {
itemListElement: [
{ "@type": "ListItem", position: 1, name: "خانه", item: origin },
{ "@type": "ListItem", position: 2, name: specialtyLabel, item: specialtyItem },
{ "@type": "ListItem", position: 3, name: `دکتر ${doctor.name}` },
{ "@type": "ListItem", position: 3, name: doctorTitle(doctor.name) },
],
}
: null;
+7
View File
@@ -46,6 +46,13 @@ export const imageUrl = (url, fallback = "/assets/images/user.png") => {
return url;
};
// نام پزشک با پیشوند «دکتر»، بدون تکرار. بعضی رکوردها خودشان با «دکتر»/«دکتر.»
// ذخیره شده‌اند؛ بدون این نرمال‌سازی خروجی «دکتر دکتر ...» می‌شود.
export const doctorTitle = (name) => {
const clean = (name || "").trim().replace(/^(دکتر|دكتر)[.،:]?\s+/, "");
return clean ? `دکتر ${clean}` : "";
};
export const convertToJalali = (date) => {
const currentDate = date;
+3 -1
View File
@@ -7,6 +7,8 @@
// متفاوت استفاده می‌شود که با هشِ (تخصص، شهر) انتخاب می‌شوند — خروجی پایدار
// (بین دو رندر تغییر نمی‌کند) ولی بین صفحات مختلف واگراست.
import { doctorTitle } from "@/helper";
function hash(...parts) {
const key = parts.join("|");
let value = 0;
@@ -63,7 +65,7 @@ export function buildSpecialtyIntro(specialtyName, cityName, doctorCount = 0) {
/** سوالات متداول صفحهٔ پزشک — منبع مشترک بلوک بصری و FAQPage schema. */
export function buildDoctorFaq(doctorName, specialtyName, cityName) {
const who = `دکتر ${doctorName}`;
const who = doctorTitle(doctorName);
return [
{
question: `چگونه از ${who} نوبت بگیرم؟`,