diff --git a/src/app/(auth)/layout.tsx b/src/app/(auth)/layout.tsx new file mode 100644 index 0000000..c6e2faf --- /dev/null +++ b/src/app/(auth)/layout.tsx @@ -0,0 +1,18 @@ +import type { Metadata } from "next"; + +export const metadata: Metadata = { + title: { + default: "ورود و ثبت‌نام | مدستاگرام", + template: "%s | مدستاگرام", + }, + description: "ورود یا ثبت‌نام در مدستاگرام", + robots: { index: false, follow: false }, +}; + +export default function AuthLayout({ + children, +}: { + children: React.ReactNode; +}) { + return children; +} diff --git a/src/app/(projects)/academy/[[...slug]]/page.tsx b/src/app/(projects)/academy/[[...slug]]/page.tsx index 31acd6f..e82892f 100644 --- a/src/app/(projects)/academy/[[...slug]]/page.tsx +++ b/src/app/(projects)/academy/[[...slug]]/page.tsx @@ -3,6 +3,8 @@ import { cookies } from "next/headers"; import InfinitePosts from "@/components/academy/InfinitePakage"; import { Metadata } from "next"; import AcademyFilter from "@/components/academy/AcademyFilter"; +import { pageSeo } from "@/config/pageSeo"; +import { generatePageMetadata } from "@/utils/generatePageMetadata"; interface IProjectsProps { params: Promise<{ slug?: string[] }>; @@ -22,40 +24,41 @@ export async function generateMetadata({ searchParams, }: IProjectsProps): Promise { const filters = await searchParams; - - // خواندن مقادیر فیلترها (اگر خالی بود مقدار پیش‌فرض در نظر گرفته میشه) + + const isDefaultAcademy = + !filters.category && + !filters.type && + !filters.search && + !filters.minPrice && + !filters.maxPrice && + !filters.hasOffer && + !filters.sortBy; + + if (isDefaultAcademy) { + return generatePageMetadata({ + title: pageSeo.academy.title, + description: pageSeo.academy.description, + path: pageSeo.academy.path, + keywords: [...pageSeo.academy.keywords], + }); + } + const categoryLabel = filters.category || "حوزه زیبایی"; const typeLabel = filters.type ? ` به صورت ${filters.type}` : ""; const descTypeLabel = filters.type ? ` بصورت ${filters.type}` : ""; - // مقادیر پیش‌فرض زمانی که هیچ فیلتری انتخاب نشده - let title = "آموزش آنلاین انواع خدمات حوزه زیبایی و مدلینگ - مدستاگرام"; - let description = "آموزش آنلاین تخصصی و حرفه‌ای از انواع اساتید حوزه زیبایی در همه زمینه‌ها اعم از آرایشگری، مدلینگ و عکاسی - مدستاگرام"; + const title = `آموزش ${categoryLabel}${typeLabel} | آموزشگاه مدستاگرام`; + const description = `آموزش تخصصی و حرفه‌ای ${categoryLabel}${descTypeLabel} در آموزشگاه مدستاگرام. پکیج‌های آموزشی زیبایی، میکاپ، مدلینگ و عکاسی.`; - // اگر کاربر فیلتر "دسته بندی" یا "نوع" رو انتخاب کرده بود، متن‌ها داینامیک میشن - if (filters.category || filters.type) { - title = `آموزش آنلاین انواع خدمات ${categoryLabel}${typeLabel} - مدستاگرام`; - description = `آموزش آنلاین تخصصی و حرفه ای خدمات ${categoryLabel}${descTypeLabel} در مدستاگرام`; - } - - // ساخت آدرس URL داینامیک بر اساس فیلترها - let canonicalUrl = "https://modstagram.com/academy"; const queryParams = new URLSearchParams(); if (filters.category) queryParams.append("category", filters.category); if (filters.type) queryParams.append("type", filters.type); - const queryString = queryParams.toString(); - if (queryString) { - canonicalUrl += `?${queryString}`; - } + const path = queryString + ? `${pageSeo.academy.path}?${queryString}` + : pageSeo.academy.path; - return { - title, - description, - alternates: { - canonical: canonicalUrl, - }, - }; + return generatePageMetadata({ title, description, path }); } export default async function Projects({ @@ -89,6 +92,9 @@ export default async function Projects({ return ( +

+ {pageSeo.academy.title.replace(" | مدستاگرام", "")} +

diff --git a/src/app/(projects)/academy/[id]/[title]/page.tsx b/src/app/(projects)/academy/[id]/[title]/page.tsx index f393a7f..e923828 100644 --- a/src/app/(projects)/academy/[id]/[title]/page.tsx +++ b/src/app/(projects)/academy/[id]/[title]/page.tsx @@ -1,16 +1,15 @@ import { Metadata } from "next"; import CourseDetail from "./CourseClient"; +import { generatePageMetadata } from "@/utils/generatePageMetadata"; -// نوع Props را به‌روز کردیم که params یک Promise باشد type Props = { params: Promise<{ id: string; title: string }>; }; -// تابع metadata با await روی params export async function generateMetadata({ params }: Props): Promise { - try { - const { id } = await params; // اول await می‌کنیم، بعد id می‌گیریم + const { id, title: slugTitle } = await params; + try { const res = await fetch( `https://app.modstagram.ir/api/v1/academy/academy/get/curses?page=1&limit=20&status=accept&_id=${id}`, { cache: "no-store" } @@ -32,23 +31,25 @@ export async function generateMetadata({ params }: Props): Promise { .replace(/<[^>]*>?/gm, "") .substring(0, 150); - return { - title: `${courseName} - ${category} - مدستاگرام`, - description: `${category} - ${cleanCaption} - مدرس: ${teacher} - مدستاگرام`, - }; + return generatePageMetadata({ + title: `${courseName} | ${category} | آموزشگاه مدستاگرام`, + description: `${cleanCaption || courseName}. دسته: ${category}. مدرس: ${teacher}. پکیج آموزشی تخصصی در آموزشگاه مدستاگرام.`, + path: `/academy/${id}/${encodeURIComponent(slugTitle || courseName)}`, + type: "article", + }); } } catch (error) { console.error("خطا در دریافت اطلاعات سئو:", error); } - return { - title: "جزئیات دوره - مدستاگرام", - description: "توضیحات دوره آکادمی - مدستاگرام", - }; + return generatePageMetadata({ + title: "جزئیات دوره | آموزشگاه مدستاگرام", + description: "مشاهده جزئیات پکیج آموزشی در آموزشگاه مدستاگرام.", + path: `/academy/${id}/${encodeURIComponent(slugTitle || "course")}`, + }); } -// صفحه اصلی را async کردیم تا بتوانیم params را await کنیم export default async function CoursePage({ params }: Props) { - const { id } = await params; // استخراج id از params + const { id } = await params; return ; } diff --git a/src/app/(projects)/new-project/layout.tsx b/src/app/(projects)/new-project/layout.tsx index 365ca55..6fe060f 100644 --- a/src/app/(projects)/new-project/layout.tsx +++ b/src/app/(projects)/new-project/layout.tsx @@ -1,5 +1,12 @@ import Header from "@/components/main/Header"; import TabNavigation from "@/components/TabNavigation"; +import type { Metadata } from "next"; + +export const metadata: Metadata = { + title: "ثبت پروژه جدید | مدستاگرام", + description: "ثبت درخواست همکاری و پروژه جدید در مدستاگرام", + robots: { index: false, follow: false }, +}; export default function Layout({ children }: { children: React.ReactNode }) { return ( diff --git a/src/app/(projects)/projects/[id]/[title]/page.tsx b/src/app/(projects)/projects/[id]/[title]/page.tsx index 489962e..4012359 100644 --- a/src/app/(projects)/projects/[id]/[title]/page.tsx +++ b/src/app/(projects)/projects/[id]/[title]/page.tsx @@ -2,6 +2,7 @@ import { Metadata } from "next"; import { Suspense } from "react"; import ProjectDetailClient from "./ProjectDetailClient"; import PageLoader from "@/components/ui/PageLoader"; +import { generatePageMetadata } from "@/utils/generatePageMetadata"; type ProjectDetailPageProps = { params: Promise<{ id: string; title: string }>; @@ -10,13 +11,14 @@ type ProjectDetailPageProps = { export async function generateMetadata({ params, }: ProjectDetailPageProps): Promise { - const { title } = await params; + const { id, title } = await params; const decodedTitle = decodeURIComponent(title || "پروژه"); - return { - title: `${decodedTitle} | پروژه‌ها | مدستاگرام`, - description: `جزئیات پروژه ${decodedTitle} در مدستاگرام`, - }; + return generatePageMetadata({ + title: `${decodedTitle} | پروژه‌های مدستاگرام`, + description: `جزئیات پروژه «${decodedTitle}» در مدستاگرام. مشاهده شرایط همکاری، بودجه و ثبت پیشنهاد.`, + path: `/projects/${id}/${encodeURIComponent(decodedTitle)}`, + }); } export default async function ProjectDetailPage({ diff --git a/src/app/(projects)/projects/page.tsx b/src/app/(projects)/projects/page.tsx index e344399..15bfb74 100644 --- a/src/app/(projects)/projects/page.tsx +++ b/src/app/(projects)/projects/page.tsx @@ -4,12 +4,15 @@ import ProjectsFilter from "@/components/projects/ProjectsFilter"; import { fetchProjects } from "@/api/fetchProjects"; import { cookies } from "next/headers"; import { Metadata } from "next"; +import { pageSeo } from "@/config/pageSeo"; +import { generatePageMetadata } from "@/utils/generatePageMetadata"; -export const metadata: Metadata = { - title: "پروژه‌ها | مدستاگرام", - description: - "لیست پروژه‌های مد، زیبایی و عکاسی در مدستاگرام. پروژه مناسب خود را پیدا کنید.", -}; +export const metadata: Metadata = generatePageMetadata({ + title: pageSeo.projects.title, + description: pageSeo.projects.description, + path: pageSeo.projects.path, + keywords: [...pageSeo.projects.keywords], +}); type ProjectsPageProps = { searchParams: Promise<{ @@ -38,7 +41,9 @@ export default async function ProjectsPage({ searchParams }: ProjectsPageProps) return ( -

پروژه‌های مد و زیبایی در مدستاگرام

+

+ {pageSeo.projects.title.replace(" | مدستاگرام", "")} +

{ const [urlParams, filters] = await Promise.all([params, searchParams]); + + const isDefaultHome = + (!urlParams.slug || urlParams.slug.length === 0) && + !filters.expertise && + !filters.province && + !filters.city && + !filters.userLevel && + !filters.rateFilter && + !filters.hashtag; + + if (isDefaultHome) { + return generatePageMetadata({ + title: pageSeo.home.title, + description: pageSeo.home.description, + path: pageSeo.home.path, + keywords: [...pageSeo.home.keywords], + }); + } + let locationLabel = ""; let levelLabel = ""; @@ -36,11 +57,13 @@ export async function generateMetadata({ params, searchParams }: IModelsProps): // اولویت با متن فارسی ساخته شده در URL if (decodedText.startsWith("استخدام")) { - return { - title: `${decodedText} | مدستاگرام`, - description: `لیست برترین متخصصین مد و زیبایی: ${decodedText}`, - alternates: { canonical: "https://modstagram.com" } - }; + const title = `${decodedText} | مدستاگرام`; + const description = `لیست برترین متخصصین مد و زیبایی: ${decodedText}. پیدا کردن مدل، عکاس و آرایشگر حرفه‌ای در مدستاگرام.`; + return generatePageMetadata({ + title, + description, + path: `/${urlParams.slug.join("/")}`, + }); } const pSlug = decodeURIComponent(urlParams.slug[0]); @@ -71,12 +94,14 @@ export async function generateMetadata({ params, searchParams }: IModelsProps): const expertiseLabel = filters.expertise || "مدل، عکاس و آرایشگر"; const title = `استخدام ${expertiseLabel}${levelLabel}${locationLabel} | مدستاگرام`; - - return { - title, - description: `پلتفرم تخصصی استخدام ${expertiseLabel}. بهترین متخصصین را در مدستاگرام پیدا کنید.`, - alternates: { canonical: "https://modstagram.com" }, - }; + const description = `پلتفرم تخصصی استخدام ${expertiseLabel}${locationLabel}. بهترین متخصصین حوزه زیبایی و مد را در مدستاگرام پیدا کنید.`; + + const path = + urlParams.slug && urlParams.slug.length > 0 + ? `/${urlParams.slug.join("/")}` + : pageSeo.home.path; + + return generatePageMetadata({ title, description, path }); } export default async function Models({ params, searchParams }: IModelsProps) { @@ -140,7 +165,15 @@ export default async function Models({ params, searchParams }: IModelsProps) {
{/* H1 مخفی برای بهبود سئو بر اساس آدرس صفحه */} -

استخدام {displayExpertise}{levelText} در مدستاگرام

+

+ {(!urlParams.slug || urlParams.slug.length === 0) && + !filters.expertise && + !filters.province && + !filters.city && + !filters.userLevel + ? pageSeo.home.title.replace(" | مدستاگرام", "") + : `استخدام ${displayExpertise}${levelText} در مدستاگرام`} +

{/* کامپوننت فیلتر با مقدار تخصص فعلی */} diff --git a/src/app/about-us/layout.tsx b/src/app/about-us/layout.tsx index 9c92fa3..b4b9651 100644 --- a/src/app/about-us/layout.tsx +++ b/src/app/about-us/layout.tsx @@ -1,5 +1,15 @@ import Footer from "@/components/main/Footer"; import Header from "@/components/main/Header"; +import type { Metadata } from "next"; +import { pageSeo } from "@/config/pageSeo"; +import { generatePageMetadata } from "@/utils/generatePageMetadata"; + +export const metadata: Metadata = generatePageMetadata({ + title: pageSeo.about.title, + description: pageSeo.about.description, + path: pageSeo.about.path, + keywords: [...pageSeo.about.keywords], +}); export default function Layout({ children }: { children: React.ReactNode }) { return ( diff --git a/src/app/billboards/[[...slug]]/page.tsx b/src/app/billboards/[[...slug]]/page.tsx index 904f537..8bd4408 100644 --- a/src/app/billboards/[[...slug]]/page.tsx +++ b/src/app/billboards/[[...slug]]/page.tsx @@ -4,6 +4,8 @@ import InfiniteBillboard from "@/components/billboards/InfiniteBillboard"; import BillboardsFilter from "@/components/billboards/BillboardPage/BillboardsFilter"; import { fetchBillboards } from "@/api/fetchBillboards"; import { Metadata } from "next"; +import { pageSeo } from "@/config/pageSeo"; +import { generatePageMetadata } from "@/utils/generatePageMetadata"; // درون‌ریزی دیتاها برای تبدیل متن به ID import provinces from "@/data/provinces.json"; @@ -72,20 +74,38 @@ const getSEOData = (slugSegments: string[] = [], filters: any) => { return { provinceId, cityId, category, categoryLabel, locationLabel }; }; -// --- اصلاح تایتل و دیسکریپشن --- +// --- متادیتای سئو --- export async function generateMetadata({ params, searchParams }: IBillboardsProps): Promise { const [urlParams, filters] = await Promise.all([params, searchParams]); + + const isDefaultBillboards = + (!urlParams.slug || urlParams.slug.length === 0) && + !filters.province && + !filters.city && + !filters.category && + !filters.search && + !filters.sort; + + if (isDefaultBillboards) { + return generatePageMetadata({ + title: pageSeo.billboards.title, + description: pageSeo.billboards.description, + path: pageSeo.billboards.path, + keywords: [...pageSeo.billboards.keywords], + }); + } + const { locationLabel, categoryLabel } = getSEOData(urlParams.slug, filters); - const title = `تبلیغات و بیلبورد ${categoryLabel}${locationLabel} | مدستاگرام`; - const description = `بهترین ${categoryLabel}${locationLabel}. لیست مراکز معتبر و بیلبوردهای تبلیغاتی در پلتفرم تخصصی مدستاگرام.`; + const title = `تبلیغات ${categoryLabel}${locationLabel} | بیلبورد مدستاگرام`; + const description = `بیلبورد و تبلیغات ${categoryLabel}${locationLabel} در مدستاگرام. فضای ویژه تبلیغات کسب‌وکارهای حوزه زیبایی برای دیده‌شدن بیشتر و جذب مشتری.`; - return { - title, - description, - alternates: { canonical: "https://modstagram.com/billboards" }, - openGraph: { title, description, url: "https://modstagram.com/billboards", siteName: "مدستاگرام", locale: "fa_IR", type: "website" } - }; + const path = + urlParams.slug && urlParams.slug.length > 0 + ? `/billboards/${urlParams.slug.join("/")}` + : pageSeo.billboards.path; + + return generatePageMetadata({ title, description, path }); } // --- اصلاح فیلتر و محتوا --- @@ -115,7 +135,13 @@ export default async function Billboards({ params, searchParams }: IBillboardsPr return (

- تبلیغات {categoryLabel}{locationLabel} در مدستاگرام + {(!urlParams.slug || urlParams.slug.length === 0) && + !filters.province && + !filters.city && + !filters.category && + !filters.search + ? pageSeo.billboards.title.replace(" | مدستاگرام", "") + : `تبلیغات ${categoryLabel}${locationLabel} در مدستاگرام`}

diff --git a/src/app/billboards/[id]/[title]/page.tsx b/src/app/billboards/[id]/[title]/page.tsx index 92caf66..d537957 100644 --- a/src/app/billboards/[id]/[title]/page.tsx +++ b/src/app/billboards/[id]/[title]/page.tsx @@ -73,11 +73,11 @@ export async function generateMetadata({ const address = billboard.address || `${province} ${city} ${neighborhood}`; const dynamicDescription = `${address} - ${billboard.description || ""}`.substring(0, 160); - // کلمه "مدستاگرام" توسط تابع generatePageMetadata به انتهای تایتل اضافه می‌شود return generatePageMetadata({ title: dynamicTitle, description: dynamicDescription, path: `/billboards/${id}/${encodeURIComponent(urlSlug)}`, + appendSiteName: true, }); } diff --git a/src/app/explore/layout.tsx b/src/app/explore/layout.tsx new file mode 100644 index 0000000..753759c --- /dev/null +++ b/src/app/explore/layout.tsx @@ -0,0 +1,18 @@ +import type { Metadata } from "next"; +import { pageSeo } from "@/config/pageSeo"; +import { generatePageMetadata } from "@/utils/generatePageMetadata"; + +export const metadata: Metadata = generatePageMetadata({ + title: pageSeo.explore.title, + description: pageSeo.explore.description, + path: pageSeo.explore.path, + keywords: [...pageSeo.explore.keywords], +}); + +export default function ExploreLayout({ + children, +}: { + children: React.ReactNode; +}) { + return children; +} diff --git a/src/app/explore/page.tsx b/src/app/explore/page.tsx index f4bddf7..83e3c72 100644 --- a/src/app/explore/page.tsx +++ b/src/app/explore/page.tsx @@ -6,6 +6,7 @@ import ExploreFilterBar from "@/components/explore/ExploreFilterBar"; import ExploreGrid from "@/components/explore/ExploreGrid"; import Header from "@/components/main/Header"; import { ExploreFilterId } from "@/constants/exploreFilters"; +import { pageSeo } from "@/config/pageSeo"; import { useCallback, useState } from "react"; import toast from "react-hot-toast"; @@ -54,6 +55,9 @@ export default function ExplorePage() { <>
+

+ {pageSeo.explore.title.replace(" | مدستاگرام", "")} +

+ {children} diff --git a/src/app/new-post/layout.tsx b/src/app/new-post/layout.tsx index 81128eb..574c282 100644 --- a/src/app/new-post/layout.tsx +++ b/src/app/new-post/layout.tsx @@ -2,6 +2,13 @@ import Header from "@/components/main/Header"; import TabNavigation from "@/components/TabNavigation"; import { Suspense } from "react"; import PageLoader from "@/components/ui/PageLoader"; +import type { Metadata } from "next"; + +export const metadata: Metadata = { + title: "انتشار پست | مدستاگرام", + description: "انتشار پست، ویدئو یا استوری در مدستاگرام", + robots: { index: false, follow: false }, +}; export default function Layout({ children }: { children: React.ReactNode }) { return ( diff --git a/src/app/posts/[id]/page.tsx b/src/app/posts/[id]/page.tsx index da5cf8f..5652437 100644 --- a/src/app/posts/[id]/page.tsx +++ b/src/app/posts/[id]/page.tsx @@ -1,9 +1,10 @@ import { Metadata } from "next"; import { fetchPostById } from "@/api/fetchPostById"; import PostFeedView from "@/components/posts/PostFeedView"; -import { IMAGE_BASE_URL, buildStorageUrl } from "@/components/main/BaseUrl"; +import { buildStorageUrl } from "@/components/main/BaseUrl"; import { Suspense } from "react"; import PageLoader from "@/components/ui/PageLoader"; +import { generatePageMetadata } from "@/utils/generatePageMetadata"; type Props = { params: Promise<{ id: string }> }; @@ -11,34 +12,23 @@ export async function generateMetadata({ params }: Props): Promise { const { id } = await params; const post = await fetchPostById(id); const title = post?.caption - ? `${post.caption.slice(0, 60)} | مادستاگرام` - : `پست | مادستاگرام`; + ? `${post.caption.slice(0, 60)} | مدستاگرام` + : "پست | مدستاگرام"; const description = post?.caption?.slice(0, 160) || - "مشاهده پست در مادستاگرام — پلتفرم مدلینگ و تبلیغات"; + "مشاهده پست در مدستاگرام — پلتفرم تخصصی حوزه زیبایی، مدلینگ و عکاسی"; const ogImage = post?.files?.[0]?.path ? buildStorageUrl(post.files[0].path) : undefined; - return { + return generatePageMetadata({ title, description, - alternates: { canonical: `https://modstagram.com/posts/${id}` }, - openGraph: { - title, - description, - url: `https://modstagram.com/posts/${id}`, - type: "article", - images: ogImage ? [{ url: ogImage, width: 1080, height: 1350 }] : [], - }, - twitter: { - card: "summary_large_image", - title, - description, - images: ogImage ? [ogImage] : [], - }, - robots: { index: true, follow: true }, - }; + path: `/posts/${id}`, + type: "article", + imageUrl: ogImage, + imageAlt: post?.caption?.slice(0, 80) || "پست مدستاگرام", + }); } export default async function PostPage({ params }: Props) { @@ -55,7 +45,7 @@ export default async function PostPage({ params }: Props) { __html: JSON.stringify({ "@context": "https://schema.org", "@type": "SocialMediaPosting", - headline: post.caption?.slice(0, 110) || "پست مادستاگرام", + headline: post.caption?.slice(0, 110) || "پست مدستاگرام", url: `https://modstagram.com/posts/${id}`, datePublished: post.createdAt, author: { diff --git a/src/app/search/page.tsx b/src/app/search/page.tsx index caf2952..6d11078 100644 --- a/src/app/search/page.tsx +++ b/src/app/search/page.tsx @@ -4,6 +4,8 @@ import SearchFilter from "@/components/search/SearchFilter"; import { fetchSearch } from "@/api/fetchSearch"; import InfiniteSearch from "@/components/search/InfiniteSearch"; import { Metadata } from "next"; +import { pageSeo } from "@/config/pageSeo"; +import { generatePageMetadata } from "@/utils/generatePageMetadata"; interface ISearchProps { searchParams: Promise<{ @@ -15,30 +17,24 @@ interface ISearchProps { // تبدیل متادیتای ثابت به داینامیک export async function generateMetadata({ searchParams }: ISearchProps): Promise { const { search } = await searchParams; - - const title = search - ? `نتایج جستجو برای "${search}" | مدستاگرام` - : "جستجوی بیلبوردها و پروفایل‌ها | مدستاگرام"; - const description = search - ? `نتایج جستجوی تخصصی برای ${search} در حوزه مد و زیبایی مدستاگرام.` - : "جستجو و فیلتر بیلبورد، فروشگاه، شهر و دسته‌بندی در پلتفرم مدستاگرام."; + if (!search) { + return generatePageMetadata({ + title: pageSeo.search.title, + description: pageSeo.search.description, + path: pageSeo.search.path, + keywords: [...pageSeo.search.keywords], + }); + } - return { + const title = `نتایج جستجو برای «${search}» | مدستاگرام`; + const description = `نتایج جستجوی تخصصی برای «${search}» در حوزه مد، زیبایی و مدلینگ در مدستاگرام.`; + + return generatePageMetadata({ title, description, - alternates: { - canonical: "https://modstagram.com/search", - }, - openGraph: { - title, - description, - url: "https://modstagram.com/search", - siteName: "مدستاگرام", - locale: "fa_IR", - type: "website", - } - }; + path: `${pageSeo.search.path}?search=${encodeURIComponent(search)}`, + }); } export default async function Search({ searchParams }: ISearchProps) { diff --git a/src/app/settings/layout.tsx b/src/app/settings/layout.tsx index 95fb5f0..f159beb 100644 --- a/src/app/settings/layout.tsx +++ b/src/app/settings/layout.tsx @@ -6,6 +6,8 @@ export const metadata: Metadata = { default: "تنظیمات", template: "%s | مدستاگرام", }, + description: "تنظیمات حساب کاربری در مدستاگرام", + robots: { index: false, follow: false }, }; export default function Layout({ children }: { children: React.ReactNode }) { diff --git a/src/components/seo/SiteJsonLd.tsx b/src/components/seo/SiteJsonLd.tsx new file mode 100644 index 0000000..c18e956 --- /dev/null +++ b/src/components/seo/SiteJsonLd.tsx @@ -0,0 +1,43 @@ +import { pageSeo, SITE_NAME, SITE_URL } from "@/config/pageSeo"; + +/** JSON-LD برای موتورهای جستجو و سیستم‌های هوش مصنوعی */ +export default function SiteJsonLd() { + const schema = { + "@context": "https://schema.org", + "@graph": [ + { + "@type": "Organization", + "@id": `${SITE_URL}/#organization`, + name: SITE_NAME, + url: SITE_URL, + logo: `${SITE_URL}/images/icons/256x256.png`, + description: pageSeo.home.description, + inLanguage: "fa-IR", + }, + { + "@type": "WebSite", + "@id": `${SITE_URL}/#website`, + name: SITE_NAME, + url: SITE_URL, + description: pageSeo.home.description, + inLanguage: "fa-IR", + publisher: { "@id": `${SITE_URL}/#organization` }, + potentialAction: { + "@type": "SearchAction", + target: { + "@type": "EntryPoint", + urlTemplate: `${SITE_URL}/search?search={search_term_string}`, + }, + "query-input": "required name=search_term_string", + }, + }, + ], + }; + + return ( +