كائن البيانات الوصفية وخيارات generateMetadata

تغطي هذه الصفحة جميع خيارات البيانات الوصفية المعتمدة على التكوين باستخدام generateMetadata وكائن البيانات الوصفية الثابت.

import { Metadata } from 'next'

// إما بيانات وصفية ثابتة
export const metadata: Metadata = {
  title: '...',
}

// أو بيانات وصفية ديناميكية
export async function generateMetadata({ params }) {
  return {
    title: '...',
  }
}
// إما بيانات وصفية ثابتة
export const metadata = {
  title: '...',
}

// أو بيانات وصفية ديناميكية
export async function generateMetadata({ params }) {
  return {
    title: '...',
  }
}

معلومة مفيدة:

  • تصدير كائن metadata ودالة `generateMetadata** مدعوم فقط في مكونات الخادم (Server Components)**.
  • لا يمكنك تصدير كائن metadata ودالة generateMetadata من نفس مقطع المسار.

كائن metadata

لتحديد بيانات وصفية ثابتة، قم بتصدير كائن Metadata من ملف layout.js أو page.js.

import { Metadata } from 'next'

export const metadata: Metadata = {
  title: '...',
  description: '...',
}

export default function Page() {}
export const metadata = {
  title: '...',
  description: '...',
}

export default function Page() {}

راجع حقول البيانات الوصفية للحصول على قائمة كاملة بالخيارات المدعومة.

دالة generateMetadata

يمكن تعيين البيانات الوصفية الديناميكية التي تعتمد على معلومات ديناميكية، مثل معلمات المسار الحالية، أو البيانات الخارجية، أو metadata في المقاطع الأب، عن طريق تصدير دالة generateMetadata التي تُرجع كائن Metadata.

import { Metadata, ResolvingMetadata } from 'next'

type Props = {
  params: { id: string }
  searchParams: { [key: string]: string | string[] | undefined }
}

export async function generateMetadata(
  { params, searchParams }: Props,
  parent: ResolvingMetadata
): Promise<Metadata> {
  // قراءة معلمات المسار
  const id = params.id

  // جلب البيانات
  const product = await fetch(`https://.../${id}`).then((res) => res.json())

  // الوصول الاختياري إلى البيانات الوصفية للأب وتوسيعها (بدلاً من استبدالها)
  const previousImages = (await parent).openGraph?.images || []

  return {
    title: product.title,
    openGraph: {
      images: ['/some-specific-page-image.jpg', ...previousImages],
    },
  }
}

export default function Page({ params, searchParams }: Props) {}
export async function generateMetadata({ params, searchParams }, parent) {
  // قراءة معلمات المسار
  const id = params.id

  // جلب البيانات
  const product = await fetch(`https://.../${id}`).then((res) => res.json())

  // الوصول الاختياري إلى البيانات الوصفية للأب وتوسيعها (بدلاً من استبدالها)
  const previousImages = (await parent).openGraph?.images || []

  return {
    title: product.title,
    openGraph: {
      images: ['/some-specific-page-image.jpg', ...previousImages],
    },
  }
}

export default function Page({ params, searchParams }) {}

المعلمات

تقبل دالة generateMetadata المعلمات التالية:

  • props - كائن يحتوي على معلمات المسار الحالي:

    • params - كائن يحتوي على كائن معلمات المسار الديناميكي من المقطع الجذري وصولاً إلى المقطع الذي يتم استدعاء generateMetadata منه. أمثلة:

      المسارالرابطparams
      app/shop/[slug]/page.js/shop/1{ slug: '1' }
      app/shop/[tag]/[item]/page.js/shop/1/2{ tag: '1', item: '2' }
      app/shop/[...slug]/page.js/shop/1/2{ slug: ['1', '2'] }
    • searchParams - كائن يحتوي على معلمات البحث الحالية للرابط. أمثلة:

      الرابطsearchParams
      /shop?a=1{ a: '1' }
      /shop?a=1&b=2{ a: '1', b: '2' }
      /shop?a=1&a=2{ a: ['1', '2'] }
  • parent - وعد بحل البيانات الوصفية من مقاطع المسار الأب.

القيم المُرجعة

يجب أن تُرجع generateMetadata كائن Metadata يحتوي على حقل بيانات وصفية واحد أو أكثر.

معلومة مفيدة:

  • إذا كانت البيانات الوصفية لا تعتمد على معلومات وقت التشغيل، فيجب تعريفها باستخدام كائن metadata الثابت بدلاً من generateMetadata.
  • طلبات fetch يتم تخزينها مؤقتًا تلقائيًا لنفس البيانات عبر generateMetadata، وgenerateStaticParams، والتخطيطات، والصفحات، ومكونات الخادم. يمكن استخدام cache في React إذا لم يكن fetch متاحًا.
  • searchParams متاحة فقط في مقاطع page.js.
  • يمكن أيضًا استخدام طرق Next.js redirect() وnotFound() داخل generateMetadata.

حقول البيانات الوصفية

title

يُستخدم سمة title لتعيين عنوان المستند. يمكن تعريفه كـ سلسلة نصية بسيطة أو كائن قالب اختياري.

سلسلة نصية

layout.js | page.js
export const metadata = {
  title: 'Next.js',
}
<head> output
<title>Next.js</title>

كائن القالب

import { Metadata } from 'next'

export const metadata: Metadata = {
  title: {
    template: '...',
    default: '...',
    absolute: '...',
  },
}
export const metadata = {
  title: {
    default: '...',
    template: '...',
    absolute: '...',
  },
}
الافتراضي

يمكن استخدام title.default لتوفير عنوان احتياطي لمقاطع المسار الفرعية التي لا تحدد title.

app/layout.tsx
import type { Metadata } from 'next'

export const metadata: Metadata = {
  title: {
    default: 'Acme',
  },
}
app/about/page.tsx
import type { Metadata } from 'next'

export const metadata: Metadata = {}

// الناتج: <title>Acme</title>
القالب

يمكن استخدام title.template لإضافة بادئة أو لاحقة إلى titles المعرفة في مقاطع المسار الفرعية.

import { Metadata } from 'next'

export const metadata: Metadata = {
  title: {
    template: '%s | Acme',
    default: 'Acme', // مطلوب افتراضي عند إنشاء قالب
  },
}
export const metadata = {
  title: {
    template: '%s | Acme',
    default: 'Acme', // مطلوب افتراضي عند إنشاء قالب
  },
}
import { Metadata } from 'next'

export const metadata: Metadata = {
  title: 'About',
}

// الناتج: <title>About | Acme</title>
export const metadata = {
  title: 'About',
}

// الناتج: <title>About | Acme</title>

معلومة مفيدة:

  • title.template يطبق على مقاطع المسار الفرعية وليس المقطع الذي تم تعريفه فيه. هذا يعني:

    • title.default مطلوب عند إضافة title.template.
    • title.template المعرفة في layout.js لن تطبق على title المعرفة في page.js لنفس مقطع المسار.
    • title.template المعرفة في page.js ليس لها تأثير لأن الصفحة دائمًا هي المقطع النهائي (ليس لديها أي مقاطع مسار فرعية).
  • title.template ليس له تأثير إذا لم يحدد المسار title أو title.default.

المطلق

يمكن استخدام title.absolute لتوفير عنوان يتجاهل title.template المعرفة في المقاطع الأب.

import { Metadata } from 'next'

export const metadata: Metadata = {
  title: {
    template: '%s | Acme',
  },
}
export const metadata = {
  title: {
    template: '%s | Acme',
  },
}
import { Metadata } from 'next'

export const metadata: Metadata = {
  title: {
    absolute: 'About',
  },
}

// الناتج: <title>About</title>
export const metadata = {
  title: {
    absolute: 'About',
  },
}

// الناتج: <title>About</title>

معلومة مفيدة:

  • layout.js

    • title (سلسلة نصية) و title.default يحددان العنوان الافتراضي للمقاطع الفرعية (التي لا تحدد title الخاصة بها). ستعزز title.template من أقرب مقطع أب إذا كان موجودًا.
    • title.absolute يحدد العنوان الافتراضي للمقاطع الفرعية. يتجاهل title.template من المقاطع الأب.
    • title.template يحدد قالب عنوان جديد للمقاطع الفرعية.
  • page.js

    • إذا لم تحدد الصفحة عنوانها الخاص، سيتم استخدام العنوان المحلول لأقرب أب.
    • title (سلسلة نصية) يحدد عنوان المسار. سيعزز title.template من أقرب مقطع أب إذا كان موجودًا.
    • title.absolute يحدد عنوان المسار. يتجاهل title.template من المقاطع الأب.
    • title.template ليس له تأثير في page.js لأن الصفحة دائمًا هي المقطع النهائي للمسار.

description

layout.js | page.js
export const metadata = {
  description: 'The React Framework for the Web',
}
<head> output
<meta name="description" content="The React Framework for the Web" />

الحقول الأساسية

layout.js | page.js
export const metadata = {
  generator: 'Next.js',
  applicationName: 'Next.js',
  referrer: 'origin-when-cross-origin',
  keywords: ['Next.js', 'React', 'JavaScript'],
  authors: [{ name: 'Seb' }, { name: 'Josh', url: 'https://nextjs.org' }],
  creator: 'Jiachi Liu',
  publisher: 'Sebastian Markbåge',
  formatDetection: {
    email: false,
    address: false,
    telephone: false,
  },
}
<head> output
<meta name="application-name" content="Next.js" />
<meta name="author" content="Seb" />
<link rel="author" href="https://nextjs.org" />
<meta name="author" content="Josh" />
<meta name="generator" content="Next.js" />
<meta name="keywords" content="Next.js,React,JavaScript" />
<meta name="referrer" content="origin-when-cross-origin" />
<meta name="color-scheme" content="dark" />
<meta name="creator" content="Jiachi Liu" />
<meta name="publisher" content="Sebastian Markbåge" />
<meta name="format-detection" content="telephone=no, address=no, email=no" />

metadataBase

metadataBase هو خيار ملائم لتعيين بادئة عنوان URL أساسي لحقول metadata التي تتطلب عنوان URL مكتمل.

  • يسمح metadataBase لحقول metadata المعتمدة على URL المعرفة في مقطع المسار الحالي وما تحته باستخدام مسار نسبي بدلاً من عنوان URL المطلق المطلوب.
  • سيتم دمج المسار النسبي للحقل مع metadataBase لتكوين عنوان URL مكتمل.
  • إذا لم يتم تكوينه، يتم تعبئة metadataBase تلقائيًا بـ قيمة افتراضية.
layout.js | page.js
export const metadata = {
  metadataBase: new URL('https://acme.com'),
  alternates: {
    canonical: '/',
    languages: {
      'en-US': '/en-US',
      'de-DE': '/de-DE',
    },
  },
  openGraph: {
    images: '/og-image.png',
  },
}
<head> output
<link rel="canonical" href="https://acme.com" />
<link rel="alternate" hreflang="en-US" href="https://acme.com/en-US" />
<link rel="alternate" hreflang="de-DE" href="https://acme.com/de-DE" />
<meta property="og:image" content="https://acme.com/og-image.png" />

معلومة مفيدة:

  • يتم تعيين metadataBase عادةً في app/layout.js الجذر لتطبيقه على حقول metadata المعتمدة على URL عبر جميع المسارات.
  • يمكن تكوين جميع حقول metadata المعتمدة على URL التي تتطلب عناوين URL مطلقة باستخدام خيار metadataBase.
  • يمكن أن يحتوي metadataBase على نطاق فرعي مثل https://app.acme.com أو مسار أساسي مثل https://acme.com/start/from/here
  • إذا قدم حقل metadata عنوان URL مطلقًا، سيتم تجاهل metadataBase.
  • استخدام مسار نسبي في حقل metadata يعتمد على URL دون تكوين metadataBase سيؤدي إلى خطأ في البناء.
  • سيقوم Next.js بتطبيع الشرطات المكررة بين metadataBase (مثل https://acme.com/) وحقل نسبي (مثل /path) إلى شرطة واحدة (مثل https://acme.com/path)

القيمة الافتراضية

إذا لم يتم تكوينه، فإن metadataBase له قيمة افتراضية

  • عند اكتشاف VERCEL_URL: https://${process.env.VERCEL_URL وإلا فإنه يعود إلى http://localhost:${process.env.PORT || 3000}.
  • عند تجاوز الافتراضي، نوصي باستخدام متغيرات البيئة لحساب عنوان URL. هذا يسمح بتكوين عنوان URL لبيئات التطوير المحلية، والاختبار، والإنتاج.

تكوين URL

يفضل تكوين URL نية المطور على دلالات اجتياز الدليل الافتراضية.

  • يتم تطبيع الشرطات في نهاية metadataBase وحقول metadata.
  • يتم التعامل مع المسار "المطلق" في حقل metadata (الذي عادةً ما يستبدل مسار URL بالكامل) على أنه مسار "نسبي" (يبدأ من نهاية metadataBase).

على سبيل المثال، بالنظر إلى metadataBase التالي:

import { Metadata } from 'next'

export const metadata: Metadata = {
  metadataBase: new URL('https://acme.com'),
}
export const metadata = {
  metadataBase: new URL('https://acme.com'),
}

سيتم حل أي حقول metadata التي ترث metadataBase أعلاه وتعيين قيمتها الخاصة على النحو التالي:

حقل metadataعنوان URL المحلول
/https://acme.com
./https://acme.com
paymentshttps://acme.com/payments
/paymentshttps://acme.com/payments
./paymentshttps://acme.com/payments
../paymentshttps://acme.com/payments
https://beta.acme.com/paymentshttps://beta.acme.com/payments

openGraph

layout.js | page.js
export const metadata = {
  openGraph: {
    title: 'Next.js',
    description: 'إطار عمل React للويب',
    url: 'https://nextjs.org',
    siteName: 'Next.js',
    images: [
      {
        url: 'https://nextjs.org/og.png', // يجب أن يكون عنوان URL مطلقًا
        width: 800,
        height: 600,
      },
      {
        url: 'https://nextjs.org/og-alt.png', // يجب أن يكون عنوان URL مطلقًا
        width: 1800,
        height: 1600,
        alt: 'النص البديل المخصص الخاص بي',
      },
    ],
    videos: [
      {
        url: 'https://nextjs.org/video.mp4', // يجب أن يكون عنوان URL مطلقًا
        width: 800,
        height: 600,
      },
    ],
    audio: [
      {
        url: 'https://nextjs.org/audio.mp3', // يجب أن يكون عنوان URL مطلقًا
      },
    ],
    locale: 'en_US',
    type: 'website',
  },
}
<head> output
<meta property="og:title" content="Next.js" />
<meta property="og:description" content="إطار عمل React للويب" />
<meta property="og:url" content="https://nextjs.org/" />
<meta property="og:site_name" content="Next.js" />
<meta property="og:locale" content="en_US" />
<meta property="og:image:url" content="https://nextjs.org/og.png" />
<meta property="og:image:width" content="800" />
<meta property="og:image:height" content="600" />
<meta property="og:image:url" content="https://nextjs.org/og-alt.png" />
<meta property="og:image:width" content="1800" />
<meta property="og:image:height" content="1600" />
<meta property="og:image:alt" content="النص البديل المخصص الخاص بي" />
<meta property="og:video" content="https://nextjs.org/video.mp4" />
<meta property="og:video:width" content="800" />
<meta property="og:video:height" content="600" />
<meta property="og:audio" content="https://nextjs.org/audio.mp3" />
<meta property="og:type" content="website" />
layout.js | page.js
export const metadata = {
  openGraph: {
    title: 'Next.js',
    description: 'إطار عمل React للويب',
    type: 'article',
    publishedTime: '2023-01-01T00:00:00.000Z',
    authors: ['Seb', 'Josh'],
  },
}
<head> output
<meta property="og:title" content="Next.js" />
<meta property="og:description" content="إطار عمل React للويب" />
<meta property="og:type" content="article" />
<meta property="article:published_time" content="2023-01-01T00:00:00.000Z" />
<meta property="article:author" content="Seb" />
<meta property="article:author" content="Josh" />

معلومة مفيدة:

  • قد يكون استخدام واجهة برمجة تطبيقات Metadata المعتمدة على الملفات لصور Open Graph أكثر ملاءمة. بدلاً من الحاجة إلى مزامنة تصدير التكوين مع الملفات الفعلية، ستقوم واجهة برمجة التطبيقات المعتمدة على الملفات بإنشاء بيانات وصفية صحيحة تلقائيًا لك.

robots

import type { Metadata } from 'next'

export const metadata: Metadata = {
  robots: {
    index: false,
    follow: true,
    nocache: true,
    googleBot: {
      index: true,
      follow: false,
      noimageindex: true,
      'max-video-preview': -1,
      'max-image-preview': 'large',
      'max-snippet': -1,
    },
  },
}
<head> output
<meta name="robots" content="noindex, follow, nocache" />
<meta
  name="googlebot"
  content="index, nofollow, noimageindex, max-video-preview:-1, max-image-preview:large, max-snippet:-1"
/>

icons

معلومة مفيدة: نوصي باستخدام واجهة برمجة تطبيقات Metadata المعتمدة على الملفات للأيقونات حيثما أمكن ذلك. بدلاً من الحاجة إلى مزامنة تصدير التكوين مع الملفات الفعلية، ستقوم واجهة برمجة التطبيقات المعتمدة على الملفات بإنشاء بيانات وصفية صحيحة تلقائيًا لك.

layout.js | page.js
export const metadata = {
  icons: {
    icon: '/icon.png',
    shortcut: '/shortcut-icon.png',
    apple: '/apple-icon.png',
    other: {
      rel: 'apple-touch-icon-precomposed',
      url: '/apple-touch-icon-precomposed.png',
    },
  },
}
<head> output
<link rel="shortcut icon" href="/shortcut-icon.png" />
<link rel="icon" href="/icon.png" />
<link rel="apple-touch-icon" href="/apple-icon.png" />
<link
  rel="apple-touch-icon-precomposed"
  href="/apple-touch-icon-precomposed.png"
/>
layout.js | page.js
export const metadata = {
  icons: {
    icon: [
      { url: '/icon.png' },
      new URL('/icon.png', 'https://example.com'),
      { url: '/icon-dark.png', media: '(prefers-color-scheme: dark)' },
    ],
    shortcut: ['/shortcut-icon.png'],
    apple: [
      { url: '/apple-icon.png' },
      { url: '/apple-icon-x3.png', sizes: '180x180', type: 'image/png' },
    ],
    other: [
      {
        rel: 'apple-touch-icon-precomposed',
        url: '/apple-touch-icon-precomposed.png',
      },
    ],
  },
}
<head> output
<link rel="shortcut icon" href="/shortcut-icon.png" />
<link rel="icon" href="/icon.png" />
<link rel="icon" href="https://example.com/icon.png" />
<link rel="icon" href="/icon-dark.png" media="(prefers-color-scheme: dark)" />
<link rel="apple-touch-icon" href="/apple-icon.png" />
<link
  rel="apple-touch-icon-precomposed"
  href="/apple-touch-icon-precomposed.png"
/>
<link
  rel="apple-touch-icon"
  href="/apple-icon-x3.png"
  sizes="180x180"
  type="image/png"
/>

معلومة مفيدة: لم تعد علامات meta من نوع msapplication-* مدعومة في إصدارات Chromium من Microsoft Edge، وبالتالي لم تعد هناك حاجة إليها.

themeColor

مهمل: خيار themeColor في metadata مهمل اعتبارًا من Next.js 14. يرجى استخدام تكوين viewport بدلاً من ذلك.

manifest

بيان تطبيق ويب، كما هو محدد في مواصفات بيان تطبيق الويب.

layout.js | page.js
export const metadata = {
  manifest: 'https://nextjs.org/manifest.json',
}
<head> output
<link rel="manifest" href="https://nextjs.org/manifest.json" />

twitter

تستخدم مواصفات Twitter (بشكل مفاجئ) لأكثر من مجرد X (المعروف سابقًا باسم Twitter).

تعرف على المزيد حول مرجع ترميز بطاقة Twitter.

layout.js | page.js
export const metadata = {
  twitter: {
    card: 'summary_large_image',
    title: 'Next.js',
    description: 'إطار عمل React للويب',
    siteId: '1467726470533754880',
    creator: '@nextjs',
    creatorId: '1467726470533754880',
    images: ['https://nextjs.org/og.png'], // يجب أن يكون عنوان URL مطلقًا
  },
}
<head> output
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:site:id" content="1467726470533754880" />
<meta name="twitter:creator" content="@nextjs" />
<meta name="twitter:creator:id" content="1467726470533754880" />
<meta name="twitter:title" content="Next.js" />
<meta name="twitter:description" content="إطار عمل React للويب" />
<meta name="twitter:image" content="https://nextjs.org/og.png" />
layout.js | page.js
export const metadata = {
  twitter: {
    card: 'app',
    title: 'Next.js',
    description: 'إطار عمل React للويب',
    siteId: '1467726470533754880',
    creator: '@nextjs',
    creatorId: '1467726470533754880',
    images: {
      url: 'https://nextjs.org/og.png',
      alt: 'شعار Next.js',
    },
    app: {
      name: 'twitter_app',
      id: {
        iphone: 'twitter_app://iphone',
        ipad: 'twitter_app://ipad',
        googleplay: 'twitter_app://googleplay',
      },
      url: {
        iphone: 'https://iphone_url',
        ipad: 'https://ipad_url',
      },
    },
  },
}
<head> output
<meta name="twitter:site:id" content="1467726470533754880" />
<meta name="twitter:creator" content="@nextjs" />
<meta name="twitter:creator:id" content="1467726470533754880" />
<meta name="twitter:title" content="Next.js" />
<meta name="twitter:description" content="إطار عمل React للويب" />
<meta name="twitter:card" content="app" />
<meta name="twitter:image" content="https://nextjs.org/og.png" />
<meta name="twitter:image:alt" content="شعار Next.js" />
<meta name="twitter:app:name:iphone" content="twitter_app" />
<meta name="twitter:app:id:iphone" content="twitter_app://iphone" />
<meta name="twitter:app:id:ipad" content="twitter_app://ipad" />
<meta name="twitter:app:id:googleplay" content="twitter_app://googleplay" />
<meta name="twitter:app:url:iphone" content="https://iphone_url" />
<meta name="twitter:app:url:ipad" content="https://ipad_url" />
<meta name="twitter:app:name:ipad" content="twitter_app" />
<meta name="twitter:app:name:googleplay" content="twitter_app" />

viewport

مهمل: خيار viewport في metadata مهمل اعتبارًا من Next.js 14. يرجى استخدام تكوين viewport بدلاً من ذلك.

verification

layout.js | page.js
export const metadata = {
  verification: {
    google: 'google',
    yandex: 'yandex',
    yahoo: 'yahoo',
    other: {
      me: ['my-email', 'my-link'],
    },
  },
}
<head> output
<meta name="google-site-verification" content="google" />
<meta name="y_key" content="yahoo" />
<meta name="yandex-verification" content="yandex" />
<meta name="me" content="my-email" />
<meta name="me" content="my-link" />

appleWebApp

layout.js | page.js
export const metadata = {
  itunes: {
    appId: 'myAppStoreID',
    appArgument: 'myAppArgument',
  },
  appleWebApp: {
    title: 'تطبيق ويب Apple',
    statusBarStyle: 'black-translucent',
    startupImage: [
      '/assets/startup/apple-touch-startup-image-768x1004.png',
      {
        url: '/assets/startup/apple-touch-startup-image-1536x2008.png',
        media: '(device-width: 768px) and (device-height: 1024px)',
      },
    ],
  },
}
<head> output
<meta
  name="apple-itunes-app"
  content="app-id=myAppStoreID, app-argument=myAppArgument"
/>
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-title" content="تطبيق ويب Apple" />
<link
  href="/assets/startup/apple-touch-startup-image-768x1004.png"
  rel="apple-touch-startup-image"
/>
<link
  href="/assets/startup/apple-touch-startup-image-1536x2008.png"
  media="(device-width: 768px) and (device-height: 1024px)"
  rel="apple-touch-startup-image"
/>
<meta
  name="apple-mobile-web-app-status-bar-style"
  content="black-translucent"
/>

alternates

layout.js | page.js
export const metadata = {
  alternates: {
    canonical: 'https://nextjs.org',
    languages: {
      'en-US': 'https://nextjs.org/en-US',
      'de-DE': 'https://nextjs.org/de-DE',
    },
    media: {
      'only screen and (max-width: 600px)': 'https://nextjs.org/mobile',
    },
    types: {
      'application/rss+xml': 'https://nextjs.org/rss',
    },
  },
}
<head> output
<link rel="canonical" href="https://nextjs.org" />
<link rel="alternate" hreflang="en-US" href="https://nextjs.org/en-US" />
<link rel="alternate" hreflang="de-DE" href="https://nextjs.org/de-DE" />
<link
  rel="alternate"
  media="only screen and (max-width: 600px)"
  href="https://nextjs.org/mobile"
/>
<link
  rel="alternate"
  type="application/rss+xml"
  href="https://nextjs.org/rss"
/>
layout.js | page.js
export const metadata = {
  appLinks: {
    ios: {
      url: 'https://nextjs.org/ios',
      app_store_id: 'app_store_id',
    },
    android: {
      package: 'com.example.android/package',
      app_name: 'app_name_android',
    },
    web: {
      url: 'https://nextjs.org/web',
      should_fallback: true,
    },
  },
}
<head> output
<meta property="al:ios:url" content="https://nextjs.org/ios" />
<meta property="al:ios:app_store_id" content="app_store_id" />
<meta property="al:android:package" content="com.example.android/package" />
<meta property="al:android:app_name" content="app_name_android" />
<meta property="al:web:url" content="https://nextjs.org/web" />
<meta property="al:web:should_fallback" content="true" />

archives

يصف مجموعة من السجلات أو المستندات أو المواد الأخرى ذات الأهمية التاريخية (المصدر).

layout.js | page.js
export const metadata = {
  archives: ['https://nextjs.org/13'],
}
<head> output
<link rel="archives" href="https://nextjs.org/13" />

assets

layout.js | page.js
export const metadata = {
  assets: ['https://nextjs.org/assets'],
}
<head> output
<link rel="assets" href="https://nextjs.org/assets" />

bookmarks

layout.js | page.js
export const metadata = {
  bookmarks: ['https://nextjs.org/13'],
}
<head> output
<link rel="bookmarks" href="https://nextjs.org/13" />

category

layout.js | page.js
export const metadata = {
  category: 'technology',
}
<head> output
<meta name="category" content="technology" />

facebook

يمكنك توصيل تطبيق Facebook أو حساب Facebook بصفحة الويب الخاصة بك لبعض ملحقات Facebook الاجتماعية توثيق Facebook

معلومة مفيدة: يمكنك تحديد إما appId أو admins، ولكن ليس كلاهما.

layout.js | page.js
export const metadata = {
  facebook: {
    appId: '12345678',
  },
}
<head> output
<meta property="fb:app_id" content="12345678" />
layout.js | page.js
export const metadata = {
  facebook: {
    admins: '12345678',
  },
}
<head> output
<meta property="fb:admins" content="12345678" />

إذا كنت تريد إنشاء علامات meta متعددة من نوع fb:admins، يمكنك استخدام قيمة مصفوفة.

layout.js | page.js
export const metadata = {
  facebook: {
    admins: ['12345678', '87654321'],
  },
}
<head> output
<meta property="fb:admins" content="12345678" />
<meta property="fb:admins" content="87654321" />

other

يجب أن تغطي جميع خيارات البيانات الوصفية باستخدام الدعم المدمج. ومع ذلك، قد تكون هناك علامات بيانات وصفية مخصصة خاصة بموقعك، أو علامات بيانات وصفية جديدة تم إصدارها للتو. يمكنك استخدام خيار other لعرض أي علامة بيانات وصفية مخصصة.

layout.js | page.js
export const metadata = {
  other: {
    custom: 'meta',
  },
}
<head> output
<meta name="custom" content="meta" />

إذا كنت تريد إنشاء علامات meta متعددة بنفس المفتاح، يمكنك استخدام قيمة مصفوفة.

layout.js | page.js
export const metadata = {
  other: {
    custom: ['meta1', 'meta2'],
  },
}
<head> output
<meta name="custom" content="meta1" /> <meta name="custom" content="meta2" />

البيانات الوصفية غير المدعومة

الأنواع التالية من البيانات الوصفية لا تدعم حاليًا بشكل مدمج. ومع ذلك، لا يزال يمكن عرضها في التنسيق (layout) أو الصفحة نفسها.

البيانات الوصفيةالتوصية
<meta http-equiv="...">استخدم رؤوس HTTP المناسبة عبر redirect()، البرمجية الوسيطة (Middleware)، رؤوس الأمان
<base>عرض الوسم في التنسيق أو الصفحة نفسها.
<noscript>عرض الوسم في التنسيق أو الصفحة نفسها.
<style>تعرف على المزيد حول التنسيق في Next.js.
<script>تعرف على المزيد حول استخدام النصوص البرمجية (scripts).
<link rel="stylesheet" />استيراد (import) صفحات الأنماط مباشرة في التنسيق أو الصفحة نفسها.
<link rel="preload />استخدم طريقة ReactDOM المسبقة التحميل (preload)
<link rel="preconnect" />استخدم طريقة ReactDOM المسبقة الاتصال (preconnect)
<link rel="dns-prefetch" />استخدم طريقة ReactDOM المسبقة البحث عن DNS (prefetchDNS)

تلميحات الموارد

يحتوي عنصر <link> على عدد من الكلمات الرئيسية rel التي يمكن استخدامها للإشارة إلى المتصفح أن موردًا خارجيًا قد يكون مطلوبًا. يستخدم المتصفح هذه المعلومات لتطبيق تحسينات التحميل المسبق اعتمادًا على الكلمة الرئيسية.

بينما لا يدعم واجهة برمجة تطبيقات البيانات الوصفية (Metadata API) هذه التلميحات مباشرة، يمكنك استخدام طرق ReactDOM الجديدة لإدراجها بأمان في <head> المستند.

'use client'

import ReactDOM from 'react-dom'

export function PreloadResources() {
  ReactDOM.preload('...', { as: '...' })
  ReactDOM.preconnect('...', { crossOrigin: '...' })
  ReactDOM.prefetchDNS('...')

  return null
}
'use client'

import ReactDOM from 'react-dom'

export function PreloadResources() {
  ReactDOM.preload('...', { as: '...' })
  ReactDOM.preconnect('...', { crossOrigin: '...' })
  ReactDOM.prefetchDNS('...')

  return null
}

ابدأ تحميل مورد مبكرًا في دورة عرض الصفحة (في المتصفح). وثائق MDN.

ReactDOM.preload(href: string, options: { as: string })
<head> output
<link rel="preload" href="..." as="..." />

ابدأ اتصالًا مسبقًا بأصل معين. وثائق MDN.

ReactDOM.preconnect(href: string, options?: { crossOrigin?: string })
<head> output
<link rel="preconnect" href="..." crossorigin />

حاول حل اسم نطاق قبل طلب الموارد. وثائق MDN.

ReactDOM.prefetchDNS(href: string)
<head> output
<link rel="dns-prefetch" href="..." />

معلومة مفيدة:

  • هذه الطرق مدعومة حاليًا فقط في مكونات العميل (Client Components)، والتي لا تزال تُعرض من جانب الخادم (Server Side Rendered) عند التحميل الأولي للصفحة.
  • الميزات المدمجة في Next.js مثل next/font وnext/image وnext/script تتعامل تلقائيًا مع تلميحات الموارد ذات الصلة.
  • React 18.3 لا يتضمن بعد تعريفات الأنواع لـ ReactDOM.preload وReactDOM.preconnect وReactDOM.preconnectDNS. يمكنك استخدام // @ts-ignore كحل مؤقت لتجنب أخطاء النوع.

الأنواع

يمكنك إضافة أمان النوع إلى بياناتك الوصفية باستخدام نوع Metadata. إذا كنت تستخدم الملحق المدمج TypeScript في بيئة التطوير المتكاملة (IDE)، فلن تحتاج إلى إضافة النوع يدويًا، ولكن لا يزال بإمكانك إضافته صراحة إذا أردت.

كائن metadata

import type { Metadata } from 'next'

export const metadata: Metadata = {
  title: 'Next.js',
}

دالة generateMetadata

دالة عادية

import type { Metadata } from 'next'

export function generateMetadata(): Metadata {
  return {
    title: 'Next.js',
  }
}

دالة غير متزامنة (async)

import type { Metadata } from 'next'

export async function generateMetadata(): Promise<Metadata> {
  return {
    title: 'Next.js',
  }
}

مع خاصية القطعة (segment props)

import type { Metadata } from 'next'

type Props = {
  params: { id: string }
  searchParams: { [key: string]: string | string[] | undefined }
}

export function generateMetadata({ params, searchParams }: Props): Metadata {
  return {
    title: 'Next.js',
  }
}

export default function Page({ params, searchParams }: Props) {}

مع البيانات الوصفية الأصلية (parent metadata)

import type { Metadata, ResolvingMetadata } from 'next'

export async function generateMetadata(
  { params, searchParams }: Props,
  parent: ResolvingMetadata
): Promise<Metadata> {
  return {
    title: 'Next.js',
  }
}

مشاريع جافا سكريبت

لمشاريع جافا سكريبت، يمكنك استخدام JSDoc لإضافة أمان النوع.

/** @type {import("next").Metadata} */
export const metadata = {
  title: 'Next.js',
}

سجل الإصدارات

الإصدارالتغييرات
v13.2.0viewport وthemeColor وcolorScheme أصبحت قديمة لصالح تكوين viewport.
v13.2.0تم تقديم metadata وgenerateMetadata.