Metadata
Next.js یک API فرا داده (Metadata) دارد که برای تعریف metadata برنامه شما (مانند تگهای meta و link داخل المنت head HTML) جهت بهبود سئو و اشتراکپذیری در وب استفاده میشود.
دو روش برای افزودن Metadata به برنامه شما وجود دارد:
- Metadata مبتنی بر پیکربندی: یک static
metadataobject یا یک تابع پویاgenerateMetadataرا در یک فایلlayout.jsیاpage.jsخروجی بگیرید. - Metadata مبتنی بر فایل: فایلهای ویژه استاتیک یا تولید شده داینامیک را به بخشهای مسیر اضافه کنید.
با هر دوی این گزینهها، Next.js به طور خودکار عناصر <head> مرتبط را برای صفحات شما ایجاد میکند. همچنین میتوانید با استفاده از سازنده ImageResponse تصاویر OG پویا ایجاد کنید.
Metadata استاتیک
برای تعریف metadata استاتیک، یک آبجکت Metadata را از یک فایل layout.js یا page.js استاتیک صادر کنید.
import type { Metadata } from 'next'
export const metadata: Metadata = {
title: '...',
description: '...',
}
export default function Page() {}برای مشاهدهی تمام گزینههای موجود، به بخش مرجع API مراجعه کنید.
Metadata داینامیک
میتوانید از تابع generateMetadata برای fetch metadata ای که به مقادیر پویا نیاز دارد، استفاده کنید.
import type { 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> {
// read route params
const id = params.id
// fetch data
const product = await fetch(`https://.../${id}`).then((res) => res.json())
// optionally access and extend (rather than replace) parent metadata
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) {}برای مشاهدهی تمام پارامترهای موجود، به بخش مرجع API مراجعه کنید.
خوب است بدانید:
- هر دو metadata استاتیک و پویا از طریق
generateMetadataتنها در کامپوننتهای سمت سرور پشتیبانی میشوند.- درخواستهای
fetchبرای دادههای مشابه در سراسرgenerateMetadata،generateStaticParams، طرح بندی ها (Layouts)، صفحات (Pages) و کامپوننتهای سمت سرور به طور خودکار ذخیرهسازی موقت (memoized) میشوند. در صورت عدم دسترسی بهfetch، میتوان از کش React استفاده کرد.- Next.js قبل از استریم کردن رابط کاربری به کلاینت، منتظر اتمام دریافت داده داخل
generateMetadataمیماند. این کار تضمین میکند که بخش اول یک پاسخ استریمشده شامل تگهای<head>باشد.
metadata مبتنی بر فایل
این فایلهای ویژه برای metadata در دسترس هستند:
- favicon.ico, apple-icon.jpg, و icon.jpg
- opengraph-image.jpg و twitter-image.jpg
- robots.txt
- sitemap.xml
میتوانید از این موارد برای metadata استاتیک استفاده کنید، یا میتوانید این فایلها را با کد به صورت برنامهنویسی تولید کنید.
برای پیادهسازی و مثال ها، به بخش مرجع API فایلهای Metadata و تولید پویای تصویر مراجعه کنید.
رفتار
metadata مبتنی بر فایل اولویت بالاتری دارد و هر metadata مبتنی بر پیکربندی را لغو میکند.
فیلدهای پیشفرض
دو تگ meta پیشفرض وجود دارد که حتی اگر یک مسیر metadata را تعریف نکند، همیشه اضافه میشوند:
- تگ meta charset (opens in a new tab) کدگذاری کاراکتر را برای وبسایت تنظیم میکند.
- تگ meta viewport (opens in a new tab) عرض و مقیاس viewport را برای وبسایت جهت سازگاری با دستگاههای مختلف تنظیم میکند.
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />خوب است بدانید: شما میتوانید تگ پیشفرض
viewportرا بازنویسی کنید.
مرتب سازی
Metadata به ترتیب از بخش ریشه تا بخش نزدیک به صفحه نهایی page.js ارزیابی می شود. به عنوان مثال:
app/layout.tsx(طرح بندی ریشه)app/blog/layout.tsx(Nested Blog Layout)app/blog/[slug]/page.tsx(Blog Page)
ادغام Merging
با پیروی از ترتیب ارزیابی، اشیاء Metadata که از چندین بخش در یک مسیر یکسان صادر میشوند، به طور سطحی shallowly با هم ادغام میشوند تا خروجی نهایی Metadata یک مسیر را تشکیل دهند. کلیدهای تکراری بر اساس ترتیب آنها جایگزین می شوند.
این بدان معناست که metadata با فیلدهای تودرتو مانند openGraph و robots که در یک بخش قبلی تعریف شده اند، توسط آخرین بخش برای تعریف آنها، بازنویسی می شوند.
بازنویسی فیلدها
export const metadata = {
title: 'Acme',
openGraph: {
title: 'Acme',
description: 'Acme is a...',
},
}export const metadata = {
title: 'Blog',
openGraph: {
title: 'Blog',
},
}
// Output:
// <title>Blog</title>
// <meta property="og:title" content="Blog" />در مثال بالا:
titleازapp/layout.jsباtitleدرapp/blog/page.jsجایگزین می شود.- تمام فیلدهای
openGraphازapp/layout.jsدرapp/blog/page.jsجایگزین می شوند زیراapp/blog/page.jsmetadata openGraph را تنظیم می کند. به نبودنopenGraph.descriptionتوجه کنید.
اگر می خواهید برخی از فیلدهای تودرتو را بین بخش ها به اشتراک بگذارید در حالی که برخی دیگر را بازنویسی کنید، می توانید آنها را به یک متغیر جداگانه منتقل کنید:
export const openGraphImage = { images: ['http://...'] }import { openGraphImage } from './shared-metadata'
export const metadata = {
openGraph: {
...openGraphImage,
title: 'Home',
},
}import { openGraphImage } from '../shared-metadata'
export const metadata = {
openGraph: {
...openGraphImage,
title: 'About',
},
}در مثال بالا، تصویر OG بین app/layout.js و app/about/page.js به اشتراک گذاشته می شود، در حالی که titles متفاوت هستند.
وراثت فیلدها
export const metadata = {
title: 'Acme',
openGraph: {
title: 'Acme',
description: 'Acme is a...',
},
}export const metadata = {
title: 'About',
}
// Output:
// <title>About</title>
// <meta property="og:title" content="Acme" />
// <meta property="og:description" content="Acme is a..." />نکات
titleازapp/layout.jsباtitleدرapp/about/page.jsجایگزین می شود.- تمام فیلدهای
openGraphازapp/layout.jsدرapp/about/page.jsبه ارث رسیده اند زیراapp/about/page.jsmetadataopenGraphرا تنظیم نمی کند.
تولید تصویر پویا
سازنده ImageResponse به شما امکان میدهد تصاویر پویایی با استفاده از JSX و CSS ایجاد کنید. این برای ایجاد تصاویر رسانههای اجتماعی مانند تصاویر Open Graph، کارتهای توییتر و موارد دیگر مفید است.
برای استفاده از آن، میتوانید ImageResponse را از next/og ایمپورت کنید.
import { ImageResponse } from 'next/og'
export async function GET() {
return new ImageResponse(
(
<div
style={{
fontSize: 128,
background: 'white',
width: '100%',
height: '100%',
display: 'flex',
textAlign: 'center',
alignItems: 'center',
justifyContent: 'center',
}}
>
Hello world!
</div>
),
{
width: 1200,
height: 600,
}
)
}ImageResponse به خوبی با دیگر API های Next.js مانند Route Handlers و Metadata مبتنی بر فایل یکپارچه می شود. به عنوان مثال، می توانید از ImageResponse در یک فایل opengraph-image.tsx برای تولید تصاویر Open Graph در زمان ساخت build یا به صورت پویا در زمان درخواست request استفاده کنید.
ImageResponse از ویژگیهای رایج CSS پشتیبانی میکند، از جمله flexbox، absolute positioning، custom fonts، text wrapping، centering و nested images. لیست کامل ویژگیهای CSS پشتیبانیشده را ببینید: لیست ویژگیهای CSS پشتیبانیشده توسط ImageResponse
خوب است بدانید:
- مثال هایی در Vercel OG Playground (opens in a new tab) در دسترس هستند.
ImageResponseاز @vercel/og (opens in a new tab)، Satori (opens in a new tab) و Resvg برای تبدیل HTML و CSS به PNG استفاده میکند.- فقط Edge Runtime پشتیبانی میشود. Node.js پیش فرض کار نخواهد کرد.
- فقط از flexbox و زیرمجموعهای از ویژگیهای CSS پشتیبانی میشود. طرح بندی های پیشرفته (مانند display: grid) کار نخواهند کرد.
- حداکثر حجم bundle
500KBاست. حجم bundle شامل JSX، CSS، فونتها، تصاویر و سایر داراییهای شما میشود. در صورت تجاوز از این مقدار، کاهش حجم داراییها یا دریافت آنها در زمان اجرا را در نظر بگیرید.- فقط فرمتهای فونت
ttf،otfوwoffپشتیبانی میشوند. برای بهینهسازی سرعت تجزیهی فونت،ttfیاotfنسبت بهwoffارجحیت دارند.
JSON-LD
JSON-LD (opens in a new tab) فرمتی برای دادههای ساختاریافته است که میتواند توسط موتورهای جستجو برای درک محتوای شما استفاده شود. برای مثال، میتوانید از آن برای توصیف یک فرد، رویداد، سازمان، فیلم، کتاب، دستور غذا و بسیاری دیگر از انواع موجودیتها استفاده کنید.
توصیه فعلی ما برای JSON-LD این است که دادههای ساختاریافته را به عنوان یک تگ <script> در کامپوننتهای layout.js یا page.js خود ارائه دهید. برای نمونه:
export default async function Page({ params }) {
const product = await getProduct(params.id)
const jsonLd = {
'@context': 'https://schema.org',
'@type': 'Product',
name: product.name,
image: product.image,
description: product.description,
}
return (
<section>
{/* Add JSON-LD to your page */}
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }}
/>
{/* ... */}
</section>
)
}شما میتوانید دادههای ساختاریافتهی خود را با ابزار Rich Results Test (opens in a new tab) برای گوگل یا Schema Markup Validator (opens in a new tab) تأیید و تست کنید.
میتوانید JSON-LD خود را با TypeScript با استفاده از پکیج های community مانند schema-dts (opens in a new tab) تایپ کنید.
import { Product, WithContext } from 'schema-dts'
const jsonLd: WithContext<Product> = {
'@context': 'https://schema.org',
'@type': 'Product',
name: 'Next.js Sticker',
image: 'https://nextjs.org/imgs/sticker.png',
description: 'Dynamic at the speed of static.',
}