رفتن به محتوای اصلی
Next.js / Technical SEO۹ دقیقه مطالعه

راهنمای سئو فنی Next.js؛ از Metadata و Canonical تا Sitemap و Structured Data

چک‌لیست عملی برای ساخت صفحات قابل Crawl، جلوگیری از محتوای تکراری و استفاده درست از قابلیت‌های SEO در App Router.

By VOIDRA Engineering · Editorial Standard

راهنمای سئو فنی Next.js؛ از Metadata و Canonical تا Sitemap و Structured Data

بیشتر خطاهای SEO در Next.js از نبودن title شروع نمی‌شوند؛ از اینجا شروع می‌شوند که یک محتوا با چند URL قابل دسترس است، صفحه مهم فقط پس از JavaScript سنگین کامل می‌شود، Sitemap تاریخ غیرواقعی دارد یا Environment آزمایشی ناخواسته Index شده است. Metadata فقط لایه توصیف است؛ سئو فنی باید رابطه میان Content Model، URL، Rendering و Crawl را درست کند.

قبل از Code: هر Search Intent یک URL اصلی

برای Service، Article، Project و Location یک Page Type و الگوی URL مشخص تعریف کنید. پارامترهای Sort، Tracking و Filter نباید نسخه قابل Index دیگری از همان محتوا بسازند. برای هر صفحه تصمیم بگیرید:

  • آیا ارزش Index دارد؟
  • URL اصلی و پایدار چیست؟
  • صفحه‌های مشابه باید Redirect، Canonical یا noindex شوند؟
  • چه صفحه‌هایی به آن Contextual link می‌دهند؟

Canonical یک پیشنهاد قوی است، نه دستور مطلق. اگر Canonical، Internal Link، Sitemap و Redirect سیگنال‌های متفاوت بدهند، Google ممکن است URL دیگری انتخاب کند.

Metadata در App Router

برای صفحه ثابت می‌توان metadata و برای صفحه داینامیک generateMetadata تعریف کرد. Source داده باید همان Content Record معتبر باشد تا H1، Title، Canonical و Open Graph از هم جدا نشوند.

import type { Metadata } from "next";

const siteUrl = new URL("https://voidra.ir");

export const metadata: Metadata = {
  metadataBase: siteUrl,
  title: "خدمات طراحی و توسعه سایت با Next.js | ویدرا",
  description: "طراحی سایت Next.js با معماری محصول‌محور، SEO و Core Web Vitals.",
  alternates: { canonical: "/services/nextjs-development" },
  openGraph: {
    type: "website",
    locale: "fa_IR",
    url: "/services/nextjs-development",
    title: "طراحی و توسعه سایت با Next.js",
    description: "معماری، طراحی، توسعه و استقرار سایت‌های حرفه‌ای.",
    images: [{ url: "/og/nextjs-development.jpg", width: 1200, height: 630 }],
  },
};

در generateMetadata، اگر Slug معتبر نیست همان Page flow باید notFound() شود؛ Metadata صفحه جعلی برای رکورد ناموجود نسازید. Titleهای Template نیز نباید نام برند را دو بار تکرار کنند.

Canonical؛ هماهنگی سیگنال‌ها مهم‌تر از Tag

Canonical خودارجاع برای صفحه اصلی مفید است. اما موارد زیر باید با آن هماهنگ باشند:

  • Sitemap فقط URL Canonical را فهرست کند.
  • لینک داخلی به URL پارامتردار یا نسخه Slash متفاوت نرود.
  • HTTP/HTTPS و Host (www/بدون www) با Redirect یکپارچه شود.
  • صفحه Canonical پاسخ 200، قابل Crawl و قابل Index باشد.
  • محتوای Alternate واقعاً مشابه باشد؛ Canonical برای پنهان‌کردن صفحه ضعیف ابزار مناسبی نیست.

robots.txt و noindex را اشتباه نگیرید

robots.txt Crawl را کنترل می‌کند، نه تضمین حذف URL از Index. اگر صفحه‌ای باید noindex دیده شود، Googlebot باید بتواند صفحه یا Header را Crawl کند. مسدودکردن هم‌زمان در robots ممکن است مشاهده noindex را ناممکن کند.

در Next.js می‌توان app/robots.ts داشت:

import type { MetadataRoute } from "next";

export default function robots(): MetadataRoute.Robots {
  return {
    rules: [{ userAgent: "*", allow: "/", disallow: ["/api/", "/preview/"] }],
    sitemap: "https://voidra.ir/sitemap.xml",
    host: "https://voidra.ir",
  };
}

برای Staging به robots.txt تکیه نکنید؛ Authentication یا Network restriction لازم است. noindex یک کنترل امنیتی نیست.

Sitemap داینامیک با `lastModified` واقعی

Sitemap باید URLهای Canonical، قابل Index و 200 را داشته باشد. تاریخ امروز برای همه URLها در هر Deploy سیگنال تغییر غیرواقعی تولید می‌کند. تاریخ واقعی انتشار یا Update محتوا را استفاده کنید.

import type { MetadataRoute } from "next";

export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
  const articles = await getPublishedArticles();

  return [
    { url: "https://voidra.ir", lastModified: new Date("2026-08-01") },
    ...articles.map((article) => ({
      url: `https://voidra.ir/blog/${article.slug}`,
      lastModified: article.updatedAt,
    })),
  ];
}

برای سایت بزرگ Sitemap را بخش‌بندی کنید. ارسال Sitemap تضمین Index نیست؛ فقط کشف URLهای ترجیحی را آسان می‌کند.

Structured Data؛ بازتاب صفحه، نه تزئین SEO

برای مقاله، BlogPosting و BreadcrumbList مناسب‌اند. داده باید با H1، نویسنده، تاریخ و تصویر قابل مشاهده هماهنگ باشد. JSON-LD را با داده قابل اعتماد بسازید و ورودی CMS را بدون Escape وارد Script نکنید.

const jsonLd = {
  "@context": "https://schema.org",
  "@type": "BlogPosting",
  headline: article.title,
  datePublished: article.publishedAt,
  dateModified: article.updatedAt,
  mainEntityOfPage: `https://voidra.ir/blog/${article.slug}`,
  image: [article.ogImage],
  author: { "@type": "Organization", name: "VOIDRA" },
};

<script
  type="application/ld+json"
  dangerouslySetInnerHTML={{
    __html: JSON.stringify(jsonLd).replace(/</g, "\\u003c"),
  }}
/>

وجود FAQ در متن به این معنا نیست که Rich Result FAQ نمایش داده می‌شود. Google نمایش FAQ را محدود کرده است؛ Schema را فقط به‌دلیل واقعیت صفحه و سیاست داده اضافه کنید، نه وعده CTR.

SSR، SSG و ISR؛ کدام برای SEO بهتر است؟

Google می‌تواند JavaScript را Render کند، اما HTML اولیه کامل و پاسخ سریع کشف و تجربه را ساده‌تر می‌کند. هیچ‌کدام از SSR، SSG یا ISR ذاتاً «SEO برتر» نیستند:

  • SSG: محتوای کم‌تغییر و تعداد URL کنترل‌شده.
  • ISR/Revalidation: محتوای CMS با Update دوره‌ای.
  • SSR/Dynamic: داده شخصی یا بسیار تازه؛ با هزینه Server و Latency.
  • Client-only: برای بخش تعاملی پس از ارائه محتوای اصلی، نه محتوای اصلی قابل جست‌وجو.

خطای رایج، Dynamic کردن کل سایت برای یک Widget کوچک یا Client-only کردن متن مقاله به‌دلیل راحتی Fetch است.

Pagination، Filter و Faceted Navigation

صفحه‌های Pagination باید لینک HTML قابل Crawl و محتوای متمایز داشته باشند. همه صفحه‌ها را Canonical به صفحه اول نکنید اگر آیتم متفاوت دارند. Filterهای کم‌ارزش را از Index خارج و Linkهای تولید بی‌نهایت را کنترل کنید. برای Filterهای دارای تقاضای واقعی، Landing Page پایدار و Curated بسازید.

سایت چندزبانه و hreflang

نسخه فارسی و انگلیسی فقط وقتی Alternate یکدیگرند که محتوای معادل داشته باشند. هر صفحه باید hreflang دوطرفه، Canonical زبان خودش و URL پایدار داشته باشد. Redirect خودکار براساس IP/زبان نباید دسترسی Crawler و کاربر به نسخه دیگر را مسدود کند.

Internal Linking؛ بخشی از معماری

Footer به‌تنهایی ارتباط موضوعی مقاله‌ها را نمی‌سازد. Pillar باید به Supporting articleها و هر Supporting article به Pillar و Service مرتبط لینک دهد. Anchor معنی‌دار و متن اطراف لینک باید دلیل ارتباط را روشن کند.

Debug: چرا صفحه Index نمی‌شود؟

به‌ترتیب بررسی کنید:

  1. پاسخ HTTP و Redirect chain.
  2. noindex در HTML یا X-Robots-Tag.
  3. robots.txt و امکان Crawl resourceها.
  4. Canonical اعلام‌شده و Canonical انتخاب‌شده Google.
  5. HTML اولیه و محتوای Rendered.
  6. لینک داخلی ورودی و حضور در Sitemap.
  7. Duplicate/Soft 404 یا محتوای بسیار کم.
  8. URL Inspection و Crawl logs.

Index نشدن همیشه Bug فنی نیست؛ ممکن است Google صفحه را کم‌ارزش یا تکراری بداند.

کنترل پس از انتشار

  • Rich Results Test برای Syntax و Eligibility.
  • URL Inspection برای Live test و Canonical.
  • Search Console برای Page indexing و Sitemap.
  • Crawl داخلی برای Status، Title، Canonical، H1 و Orphan.
  • Log/Monitoring برای 404 و 5xx.
  • Field CWV برای تجربه واقعی.

جمع‌بندی

سئو فنی Next.js یک فایل metadata نیست؛ قرارداد میان Content، URL، Rendering و عملیات است. وقتی Canonical، Sitemap، Internal Link، Status code و محتوای صفحه یک سیگنال واحد بدهند، Crawler آسان‌تر ساختار سایت را درک می‌کند. وظیفه Framework فراهم‌کردن ابزار است؛ مسئولیت معماری همچنان با تیم محصول و توسعه است.

سؤالات متداول

آیا Next.js برای SEO خوب است؟

بله، ابزارهای Rendering و Metadata مناسبی دارد؛ ولی URL architecture، محتوا، لینک داخلی و Performance تعیین‌کننده‌اند.

Canonical در Next.js کجا تعریف می‌شود؟

در App Router معمولاً از metadata.alternates.canonical یا generateMetadata استفاده می‌شود. Redirect، Sitemap و Internal Link باید با آن هماهنگ باشند.

آیا همه صفحه‌ها باید در Sitemap باشند؟

خیر؛ فقط URLهای Canonical و قابل Index که برای Search ارزش دارند. صفحه Login، Preview، Result داخلی و Filterهای کم‌ارزش معمولاً نباید باشند.

robots.txt باعث حذف صفحه از Google می‌شود؟

خیر. robots.txt Crawl را محدود می‌کند. برای حذف از Index از روش مناسب مانند noindex یا حذف/Status درست استفاده کنید و اجازه دهید Crawler سیگنال را ببیند.

SSR برای SEO بهتر از SSG است؟

نه به‌صورت مطلق. هر دو می‌توانند HTML کامل بدهند. Freshness، Cache، Cost و Latency انتخاب را تعیین می‌کنند.

Schema رتبه را افزایش می‌دهد؟

Structured Data به درک صفحه و Eligibility برخی نمایش‌ها کمک می‌کند، اما تضمین Rich Result یا رتبه نیست.

منابع رسمی و مطالعه بیشتر

معماری Crawl و Index سایت Next.js خود را قبل از رشد اصلاح کنید

اگر سایت Next.js شما URLهای Dynamic، CMS، چند زبان یا Filter دارد، یک Tag اشتباه می‌تواند فقط نشانه مشکل عمیق‌تر باشد. VOIDRA می‌تواند معماری Crawl/Index، Metadata pipeline و Page Typeهای سایت را پیش از توسعه یا Migration بررسی کند.

شروع مشاوره پروژه