كائن البيانات الوصفية وخيارات 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 مدعوم فقط في مكونات الخادم.
  • لا يمكنك تصدير كائن 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 منه. أمثلة:

      المسارURLparams
      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 - كائن يحتوي على معلمات البحث لـ URL الحالي. أمثلة:

      URLsearchParams
      /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: 'إطار عمل React للويب',
}
<head> output
<meta name="description" content="إطار عمل React للويب" />

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

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' }],
  colorScheme: 'dark',
  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: 'The React Framework for the Web',
    url: 'https://nextjs.org',
    siteName: 'Next.js',
    images: [
      {
        url: 'https://nextjs.org/og.png',
        width: 800,
        height: 600,
      },
      {
        url: 'https://nextjs.org/og-alt.png',
        width: 1800,
        height: 1600,
        alt: 'My custom alt',
      },
    ],
    locale: 'en_US',
    type: 'website',
  },
}
<head> output
<meta property="og:title" content="Next.js" />
<meta property="og:description" content="The React Framework for the Web" />
<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="My custom alt" />
<meta property="og:type" content="website" />
layout.js | page.js
export const metadata = {
  openGraph: {
    title: 'Next.js',
    description: 'The React Framework for the Web',
    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="The React Framework for the Web" />
<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" />

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

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

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

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')],
    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="apple-touch-icon" href="/apple-icon.png" />
<link
  rel="apple-touch-icon-precomposed"
  href="/apple-touch-icon-precomposed.png"
/>
<link rel="icon" href="https://example.com/icon.png" />
<link
  rel="apple-touch-icon"
  href="/apple-icon-x3.png"
  sizes="180x180"
  type="image/png"
/>

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

themeColor

تعرف على المزيد حول theme-color.

لون المظهر البسيط

layout.js | page.js
export const metadata = {
  themeColor: 'black',
}
<head> output
<meta name="theme-color" content="black" />

مع سمة media

layout.js | page.js
export const metadata = {
  themeColor: [
    { media: '(prefers-color-scheme: light)', color: 'cyan' },
    { media: '(prefers-color-scheme: dark)', color: 'black' },
  ],
}
<head> output
<meta name="theme-color" media="(prefers-color-scheme: light)" content="cyan" />
<meta name="theme-color" media="(prefers-color-scheme: dark)" content="black" />

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

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

layout.js | page.js
export const metadata = {
  twitter: {
    card: 'summary_large_image',
    title: 'Next.js',
    description: 'The React Framework for the Web',
    siteId: '1467726470533754880',
    creator: '@nextjs',
    creatorId: '1467726470533754880',
    images: ['https://nextjs.org/og.png'],
  },
}
<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="The React Framework for the Web" />
<meta name="twitter:image" content="https://nextjs.org/og.png" />
layout.js | page.js
export const metadata = {
  twitter: {
    card: 'app',
    title: 'Next.js',
    description: 'The React Framework for the Web',
    siteId: '1467726470533754880',
    creator: '@nextjs',
    creatorId: '1467726470533754880',
    images: {
      url: 'https://nextjs.org/og.png',
      alt: 'Next.js Logo',
    },
    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="The React Framework for the Web" />
<meta name="twitter:card" content="app" />
<meta name="twitter:image" content="https://nextjs.org/og.png" />
<meta name="twitter:image:alt" content="Next.js Logo" />
<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 تلقائيًا بالقيم الافتراضية التالية. عادةً، لا تكون هناك حاجة للتكوين اليدوي حيث أن الافتراضي كافٍ. ومع ذلك، يتم توفير المعلومات للاكتمال.

layout.js | page.js
export const metadata = {
  viewport: {
    width: 'device-width',
    initialScale: 1,
    maximumScale: 1,
  },
}
<head> output
<meta
  name="viewport"
  content="width=device-width, initial-scale=1, maximum-scale=1"
/>

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 Web App',
    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 Web App" />
<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" />

other

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

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

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

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

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

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

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

بينما لا يدعم واجهة برمجة تطبيقات البيانات الوصفية هذه التلميحات مباشرة، يمكنك استخدام طرق 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="..." />

جيد أن تعرف:

  • هذه الطرق مدعومة حاليًا فقط في مكونات العميل، والتي لا تزال تُعرض من جانب الخادم عند التحميل الأولي للصفحة.
  • الميزات المدمجة في 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',
  }
}

دالة غير متزامنة

import type { Metadata } from 'next'

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

مع خاصية القطعة

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) {}

مع البيانات الوصفية الأصلية

import type { Metadata, ResolvingMetadata } from 'next'

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

مشاريع JavaScript

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

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

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

الإصدارالتغييرات
v13.2.0تم تقديم metadata و generateMetadata.