- Add metadata to login and login-verify pages to prevent indexing. - Update robots.txt to disallow additional sensitive paths. - Enhance sitemap generation to filter by city and include accurate last modified dates. - Refactor canonical URL generation to support multi-domain architecture, ensuring self-canonicalization for city domains. - Remove deprecated CanonicalHandler component and streamline canonical URL handling. - Introduce safe JSON-LD output to prevent XSS vulnerabilities. - Add payment layout with appropriate metadata to prevent indexing. - Conduct a comprehensive technical SEO audit and implement necessary fixes across the application.
147 lines
4.7 KiB
JavaScript
147 lines
4.7 KiB
JavaScript
import "./globals.css";
|
|
import ThemeRegistry from "./component/ThemeRegistry";
|
|
import { Providers } from "./Providers";
|
|
import { GoogleAnalytics } from "@next/third-parties/google";
|
|
import "react-toastify/dist/ReactToastify.css";
|
|
import CustomToastify from "./CustomToastify";
|
|
import { ProvinceProvider } from "@/context/ProvinceProvider";
|
|
import { getStateInfo } from "@/lib/getStateInfo";
|
|
import { getCanonicalUrl, buildCanonicalUrl, getRequestOrigin } from "@/lib/getCanonicalUrl";
|
|
import { safeJsonLd } from "@/lib/sanitize";
|
|
import { headers } from "next/headers";
|
|
|
|
export const viewport = {
|
|
width: "device-width",
|
|
initialScale: 1,
|
|
};
|
|
|
|
export async function generateMetadata() {
|
|
const { matchedCity } = await getStateInfo();
|
|
|
|
const headersList = await headers();
|
|
const metadataBase = new URL(buildCanonicalUrl(headersList.get("host"), "/"));
|
|
|
|
const canonicalUrl = await getCanonicalUrl();
|
|
|
|
const title =
|
|
matchedCity?.title ||
|
|
(matchedCity?.name
|
|
? `نوبتدهی آنلاین پزشکان ${matchedCity.name} | نوبت 724`
|
|
: "نوبت 724 | سیستم نوبتدهی آنلاین پزشکی");
|
|
const description = matchedCity?.description || "نوبت 724 - سیستم آنلاین نوبتدهی برای پزشکان و کلینیکها. با استفاده از نوبت 724، به راحتی نوبت پزشکی خود را به صورت آنلاین رزرو کنید و از خدمات سریع و کارآمد ما بهرهمند شوید";
|
|
|
|
const baseMetadata = {
|
|
metadataBase,
|
|
title,
|
|
description,
|
|
keywords: matchedCity
|
|
? matchedCity.keywords
|
|
: "نوبت 724, نوبت دهی, رزرو نوبت, پزشک, پزشکی, کلینیک, بیمارستان, نوبت آنلاین, سیستم نوبت دهی, سیستم نوبت دهی آنلاین, سیستم نوبت دهی پزشکی, سیستم نوبت دهی کلینیک, سیستم نوبت دهی بیمارستان, سیستم نوبت دهی آنلاین پزشکی, سیستم نوبت دهی آنلاین کلینیک, سیستم نوبت دهی آنلاین بیمارستان",
|
|
openGraph: {
|
|
title,
|
|
description,
|
|
type: "website",
|
|
locale: "fa_IR",
|
|
siteName: matchedCity?.site_name || "نوبت 724",
|
|
images: ["https://nobat724.com/assets/images/logo.png"],
|
|
},
|
|
twitter: {
|
|
card: "summary_large_image",
|
|
title,
|
|
description,
|
|
images: ["https://nobat724.com/assets/images/logo.png"],
|
|
},
|
|
};
|
|
|
|
// Add noindex meta tag when DEV_MODE is TRUE
|
|
if (process.env.DEV_MODE === 'TRUE') {
|
|
baseMetadata.robots = {
|
|
index: false,
|
|
follow: false,
|
|
nocache: true,
|
|
googleBot: {
|
|
index: false,
|
|
follow: false,
|
|
noimageindex: true,
|
|
'max-video-preview': -1,
|
|
'max-image-preview': 'large',
|
|
'max-snippet': -1,
|
|
},
|
|
};
|
|
}
|
|
|
|
if (canonicalUrl) {
|
|
baseMetadata.alternates = {
|
|
canonical: canonicalUrl,
|
|
};
|
|
}
|
|
|
|
return baseMetadata;
|
|
}
|
|
|
|
export default async function RootLayout({ children }) {
|
|
const { matchedCity } = await getStateInfo();
|
|
const siteName = matchedCity?.site_name || "نوبت 724";
|
|
const siteUrl = await getRequestOrigin();
|
|
|
|
const organizationJsonLd = {
|
|
"@context": "https://schema.org",
|
|
"@type": "Organization",
|
|
name: siteName,
|
|
url: siteUrl,
|
|
logo: `${siteUrl}/assets/images/logo.png`,
|
|
};
|
|
|
|
const websiteJsonLd = {
|
|
"@context": "https://schema.org",
|
|
"@type": "WebSite",
|
|
url: siteUrl,
|
|
name: siteName,
|
|
potentialAction: {
|
|
"@type": "SearchAction",
|
|
target: `${siteUrl}/doctors?search={search_term_string}`,
|
|
"query-input": "required name=search_term_string",
|
|
},
|
|
};
|
|
|
|
return (
|
|
<html lang="fa" dir="rtl" suppressHydrationWarning>
|
|
<head>
|
|
<link
|
|
rel="preload"
|
|
href="/fonts/vazir/Vazirmatn-RD-FD-Regular.ttf"
|
|
as="font"
|
|
type="font/ttf"
|
|
crossOrigin="anonymous"
|
|
/>
|
|
<link
|
|
rel="preload"
|
|
href="/fonts/vazir/Vazirmatn-RD-FD-Bold.ttf"
|
|
as="font"
|
|
type="font/ttf"
|
|
crossOrigin="anonymous"
|
|
/>
|
|
<script
|
|
type="application/ld+json"
|
|
dangerouslySetInnerHTML={{ __html: safeJsonLd(organizationJsonLd) }}
|
|
/>
|
|
<script
|
|
type="application/ld+json"
|
|
dangerouslySetInnerHTML={{ __html: safeJsonLd(websiteJsonLd) }}
|
|
/>
|
|
</head>
|
|
<ThemeRegistry>
|
|
<body className="bg-[#FAFAFA]">
|
|
<ProvinceProvider>
|
|
<Providers>{children}</Providers>
|
|
</ProvinceProvider>
|
|
<CustomToastify />
|
|
</body>
|
|
{process.env.DEV_MODE === 'FALSE' && (
|
|
<GoogleAnalytics gaId="G-HG3RZ1PJS5" />
|
|
)}
|
|
</ThemeRegistry>
|
|
</html>
|
|
);
|
|
}
|