feat: Enhance metadata generation for About Us and Contact Us pages, implement legacy slug resolution for blog posts, and add city-specific intros
This commit is contained in:
+12
-3
@@ -3,10 +3,19 @@ import Layout from "@/components/layout/StLayout";
|
||||
import { getStateInfo } from "@/lib/getStateInfo";
|
||||
|
||||
export async function generateMetadata() {
|
||||
const { matchedCity } = await getStateInfo();
|
||||
const { matchedCity, matchedState, isRoot } = await getStateInfo();
|
||||
const siteName = matchedCity?.site_name || "نوبت 724";
|
||||
const title = `درباره ما | ${siteName}`;
|
||||
const description = `آشنایی با ${siteName}، سیستم آنلاین نوبتدهی پزشکی. هدف ما ارائه خدمات سریع و کارآمد رزرو نوبت پزشکی برای همه مردم است.`;
|
||||
const cityName = isRoot ? null : matchedCity?.name;
|
||||
const provinceName = isRoot ? null : matchedState?.name;
|
||||
|
||||
// صفحه self-canonical است؛ عنوان و توضیح باید شهری باشند وگرنه ۳۵ دامنه یک
|
||||
// متادیتا اعلام میکنند و همان duplicate با شکل تازه برمیگردد.
|
||||
const title = cityName
|
||||
? `درباره ما | نوبتدهی آنلاین پزشکان ${cityName} | ${siteName}`
|
||||
: `درباره ما | ${siteName}`;
|
||||
const description = cityName
|
||||
? `آشنایی با ${siteName}، سامانه رزرو آنلاین نوبت پزشکان ${cityName}${provinceName ? ` و ${provinceName}` : ""}. جستوجوی پزشک بر اساس تخصص و ثبت نوبت بدون تماس تلفنی.`
|
||||
: `آشنایی با ${siteName}، سیستم آنلاین نوبتدهی پزشکی. هدف ما ارائه خدمات سریع و کارآمد رزرو نوبت پزشکی برای همه مردم است.`;
|
||||
const image = "/assets/images/og-image.png";
|
||||
return {
|
||||
title,
|
||||
|
||||
+28
-3
@@ -1,7 +1,7 @@
|
||||
import { cache } from "react";
|
||||
import BlogPage from "@/components/blog";
|
||||
import Layout from "@/components/layout/StLayout";
|
||||
import { notFound } from "next/navigation";
|
||||
import { notFound, permanentRedirect } from "next/navigation";
|
||||
import { fetchReq } from "@/lib/req";
|
||||
import { getStateInfo } from "@/lib/getStateInfo";
|
||||
import { getBlogCanonicalOrigin } from "@/lib/getCanonicalUrl";
|
||||
@@ -13,6 +13,7 @@ import {
|
||||
import { safeJsonLd } from "@/lib/sanitize";
|
||||
import { decodeRouteParam } from "@/lib/routeParams";
|
||||
import { normalizeBlog, blogCover } from "@/helper";
|
||||
import legacySlugs from "@/data/blogLegacySlugs.json";
|
||||
|
||||
const API_URL = process.env.NEXT_PUBLIC_API_URL;
|
||||
|
||||
@@ -39,13 +40,31 @@ async function getScopedBlog(slug) {
|
||||
return getBlog(slug, domainScopeCityId({ matchedCity, isRoot }));
|
||||
}
|
||||
|
||||
/**
|
||||
* پست را با هر شناسهای که روزی به آن اشاره داشته پیدا میکند.
|
||||
*
|
||||
* بکاند خودش slug و uuid و topic_slug و پسوند ۸ کاراکتریِ uuid را resolve میکند.
|
||||
* چیزی که آنجا قابل resolve نیست، اسلاگهای لاتینِ نسل قبلاند: هیچ ردی در دیتابیس
|
||||
* ندارند چون هنگام تغییر عنوان بازنویسی شدند. Search Console همانها را روی
|
||||
* `behbahan-nobat.ir` ۴۰۴ گزارش کرد، پس نگاشتشان در data/blogLegacySlugs.json
|
||||
* دستی نگه داشته میشود — مقدارِ نگاشت پیشوند uuid است، نه اسلاگ مقصد، تا فیلتر
|
||||
* شهریِ همان درخواست دوباره اعمال شود و پستِ شهر دیگر ریدایرکتِ ۴۰۴ نسازد.
|
||||
*/
|
||||
async function resolveScopedBlog(slug) {
|
||||
const blog = await getScopedBlog(slug);
|
||||
if (blog) return blog;
|
||||
|
||||
const legacyUuidPrefix = legacySlugs[slug];
|
||||
return legacyUuidPrefix ? getScopedBlog(legacyUuidPrefix) : null;
|
||||
}
|
||||
|
||||
export async function generateMetadata({ params }) {
|
||||
const { slug: rawSlug } = await params;
|
||||
const slug = decodeRouteParam(rawSlug);
|
||||
const { matchedCity } = await getStateInfo();
|
||||
const siteName = matchedCity?.site_name || "نوبت 724";
|
||||
|
||||
const blog = await getScopedBlog(slug);
|
||||
const blog = await resolveScopedBlog(slug);
|
||||
if (!blog) notFound();
|
||||
|
||||
try {
|
||||
@@ -123,9 +142,15 @@ async function Blog({ params }) {
|
||||
const slug = decodeRouteParam(rawSlug);
|
||||
const slugPath = encodeURIComponent(slug);
|
||||
|
||||
const blog = normalizeBlog(await getScopedBlog(slug));
|
||||
const blog = normalizeBlog(await resolveScopedBlog(slug));
|
||||
if (!blog) notFound();
|
||||
|
||||
// اسلاگ کهنه (عنوان عوض شده یا نسل لاتین) به آدرس قطعی منتقل میشود؛ دو URL برای
|
||||
// یک محتوا باقی نمیماند و لینکهای قدیمیِ ایندکسشده اعتبارشان را میبرند.
|
||||
if (blog.slug && blog.slug !== slug) {
|
||||
permanentRedirect(`/blog/${encodeURIComponent(blog.slug)}`);
|
||||
}
|
||||
|
||||
const blogCityId = extractEntityCityId(blog);
|
||||
const blogCity = findCityById(blogCityId);
|
||||
const origin = getBlogCanonicalOrigin(blogCityId);
|
||||
|
||||
@@ -1,5 +1,30 @@
|
||||
import ContactUsPage from "@/components/contactUs";
|
||||
import Layout from "@/components/layout/StLayout";
|
||||
import { getStateInfo } from "@/lib/getStateInfo";
|
||||
|
||||
export async function generateMetadata() {
|
||||
const { matchedCity, matchedState, isRoot } = await getStateInfo();
|
||||
const siteName = matchedCity?.site_name || "نوبت 724";
|
||||
const cityName = isRoot ? null : matchedCity?.name;
|
||||
const provinceName = isRoot ? null : matchedState?.name;
|
||||
|
||||
// صفحه self-canonical است؛ عنوان و توضیح هم باید شهری باشند وگرنه ۳۵ دامنه
|
||||
// یک متادیتا اعلام میکنند.
|
||||
const title = cityName
|
||||
? `تماس با ما | نوبتدهی آنلاین ${cityName} | ${siteName}`
|
||||
: `تماس با ما | ${siteName}`;
|
||||
const description = cityName
|
||||
? `راههای ارتباط با ${siteName}: تلفن، واتساپ و ایمیل. پشتیبانی رزرو و لغو نوبت پزشکان ${cityName}${provinceName ? ` و ${provinceName}` : ""}.`
|
||||
: `راههای ارتباط با ${siteName}: تلفن، واتساپ و ایمیل. پشتیبانی رزرو و لغو نوبت آنلاین پزشکان.`;
|
||||
const image = "/assets/images/og-image.png";
|
||||
|
||||
return {
|
||||
title,
|
||||
description,
|
||||
openGraph: { title, description, images: [image] },
|
||||
twitter: { card: "summary_large_image", title, description, images: [image] },
|
||||
};
|
||||
}
|
||||
|
||||
function ContactUs() {
|
||||
return (
|
||||
|
||||
Reference in New Issue
Block a user