generateMetadata
이 페이지는 generateMetadata 및 정적 메타데이터 객체를 사용한 구성 기반 메타데이터 옵션을 모두 다룹니다.
import type { 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 객체
정적 메타데이터를 정의하려면 layout.js 또는 page.js 파일에서 Metadata 객체를 내보내세요.
import type { 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 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> {
// 경로 매개변수 읽기
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가 호출된 세그먼트까지의 동적 경로 매개변수 객체를 포함하는 객체입니다. 예시:경로 URL paramsapp/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의 검색 매개변수 (opens in a new tab)를 포함하는 객체입니다. 예시:URL 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 객체를 반환해야 합니다.
알아두면 좋은 정보:
- 메타데이터가 런타임 정보에 의존하지 않는 경우,
generateMetadata대신 정적metadata객체를 사용하여 정의해야 합니다.fetch요청은generateMetadata,generateStaticParams, 레이아웃, 페이지 및 서버 컴포넌트 간에 동일한 데이터를 위해 자동으로 메모이제이션됩니다.fetch가 사용 불가능한 경우, Reactcache를 사용할 수 있습니다.searchParams는page.js세그먼트에서만 사용할 수 있습니다.redirect()및notFound()Next.js 메서드는generateMetadata내에서도 사용할 수 있습니다.
메타데이터 필드
title
title 속성은 문서의 제목을 설정하는 데 사용됩니다. 단순한 문자열 또는 선택적인 템플릿 객체로 정의할 수 있습니다.
문자열
export const metadata = {
title: 'Next.js',
}<title>Next.js</title>템플릿 객체
import type { Metadata } from 'next'
export const metadata: Metadata = {
title: {
template: '...',
default: '...',
absolute: '...',
},
}export const metadata = {
title: {
default: '...',
template: '...',
absolute: '...',
},
}기본값
title.default는 title을 정의하지 않은 하위 경로 세그먼트에 대체 제목을 제공하는 데 사용할 수 있습니다.
import type { Metadata } from 'next'
export const metadata: Metadata = {
title: {
default: 'Acme',
},
}import type { Metadata } from 'next'
export const metadata: Metadata = {}
// 출력: <title>Acme</title>템플릿
title.template는 하위 경로 세그먼트에서 정의된 title에 접두사 또는 접미사를 추가하는 데 사용할 수 있습니다.
import type { Metadata } from 'next'
export const metadata: Metadata = {
title: {
template: '%s | Acme',
default: 'Acme', // 템플릿을 생성할 때 기본값이 필요합니다
},
}export const metadata = {
title: {
template: '%s | Acme',
default: '
Acme', // 템플릿을 생성할 때 기본값이 필요합니다
},
}import type { 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.template를 추가할 때title.default는 필수입니다.layout.js에 정의된title.template는 동일한 경로 세그먼트의page.js에 정의된title에 적용되지 않습니다.page.js에 정의된title.template는 효과가 없습니다. 페이지는 항상 종단 세그먼트(하위 경로 세그먼트가 없음)이기 때문입니다.경로에
title또는title.default가 정의되지 않은 경우,title.template는 효과가 없습니다.
절대값
title.absolute는 상위 세그먼트에 설정된 title.template을 무시하는 제목을 제공하는 데 사용할 수 있습니다.
import type { Metadata } from 'next'
export const metadata: Metadata = {
title: {
template: '%s | Acme',
},
}export const metadata = {
title: {
template: '%s | Acme',
},
}import type { 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을 무시합니다.page.js의title.template는 경로의 종단 세그먼트이기 때문에 효과가 없습니다.
description
export const metadata = {
description: 'The React Framework for the Web',
}<meta name="description" content="The React Framework for the Web" />기본 필드
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,
},
}<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를 사용하면 현재 경로 세그먼트 및 하위 세그먼트에 정의된 URL 기반metadata필드가 상대 경로를 사용할 수 있습니다.- 필드의 상대 경로는
metadataBase와 함께 구성되어 완전히 자격을 갖춘 URL이 됩니다. - 구성되지 않은 경우,
metadataBase는 기본 값으로 자동으로 채워집니다.
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',
},
}<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는 URL 기반metadata필드가 모든 경로에 적용되도록 루트app/layout.js에 설정됩니다.- 절대 URL이 필요한 모든 URL 기반
metadata필드는metadataBase옵션으로 구성할 수 있습니다.metadataBase는 하위 도메인(예:https://app.acme.com) 또는 기본 경로(예:https://acme.com/start/from/here)를 포함할 수 있습니다.metadata필드가 절대 URL을 제공하는 경우metadataBase는 무시됩니다.- URL 기반
metadata필드에서 상대 경로를 사용하고metadataBase를 구성하지 않으면 빌드 오류가 발생합니다.- Next.js는
metadataBase(예:https://acme.com/)와 상대 필드(예:/path) 사이의 중복 슬래시를 하나의 슬래시(예:https://acme.com/path)로 정규화합니다.
기본 값
구성되지 않은 경우, metadataBase는 기본 값을 가집니다.
Vercel에서:
- 프로덕션 배포의 경우
VERCEL_PROJECT_PRODUCTION_URL이 사용됩니다.- 미리보기 배포의 경우
VERCEL_BRANCH_URL이 우선 순위를 가지며, 존재하지 않을 경우VERCEL_URL로 대체됩니다.이러한 값이 존재하는 경우 기본 값으로 사용되며, 그렇지 않으면
http://localhost:${process.env.PORT || 3000}으로 대체됩니다. 이는 오픈 그래프 이미지가 로컬 빌드 및 Vercel 미리보기 및 프로덕션 배포에서 작동할 수 있도록 합니다. 기본 값을 재정의할 때는 환경 변수를 사용하여 URL을 계산하는 것이 좋습니다. 이를 통해 로컬 개발, 스테이징 및 프로덕션 환경에 대한 URL을 구성할 수 있습니다.이러한 환경 변수에 대한 자세한 내용은 시스템 환경 변수 (opens in a new tab) 문서를 참조하세요.
URL 구성
URL 구성은 기본 디렉토리 탐색 의미보다 개발자의 의도를 우선합니다.
metadataBase와metadata필드 사이의 후행 슬래시는 정규화됩니다.- "절대" 경로는 "상대" 경로로 간주됩니다.
예를 들어, 다음과 같은 metadataBase를 가정합니다:
import type { Metadata } from 'next'
export const metadata: Metadata = {
metadataBase: new URL('https
://acme.com'),
}export const metadata = {
metadataBase: new URL('https://acme.com'),
}다음과 같이 자신의 값을 설정한 metadata 필드는 다음과 같이 해결됩니다:
metadata 필드 | 해결된 URL |
|---|---|
/ | https://acme.com |
./ | https://acme.com |
payments | https://acme.com/payments |
/payments | https://acme.com/payments |
./payments | https://acme.com/payments |
../payments | https://acme.com/payments |
https://beta.acme.com/payments | https://beta.acme.com/payments |
openGraph
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', // 반드시 절대 URL이어야 함
width: 800,
height: 600,
},
{
url: 'https://nextjs.org/og-alt.png', // 반드시 절대 URL이어야 함
width: 1800,
height: 1600,
alt: 'My custom alt',
},
],
videos: [
{
url: 'https://nextjs.org/video.mp4', // 반드시 절대 URL이어야 함
width: 800,
height: 600,
},
],
locale: 'en_US',
type: 'website',
},
}<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" />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'],
},
}<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" />알아두면 좋은 정보:
- 오픈 그래프 이미지에 대해서는 파일 기반 메타데이터 API를 사용하는 것이 더 편리할 수 있습니다. 구성 내보내기를 실제 파일과 동기화할 필요 없이 파일 기반 API가 자동으로 올바른 메타데이터를 생성해줍니다.
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,
},
},
}<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
알아두면 좋은 정보: 가능하면 아이콘에 대해 파일 기반 메타데이터 API를 사용하는 것이 좋습니다. 구성 내보내기를 실제 파일과 동기화할 필요 없이 파일 기반 API가 자동으로 올바른 메타데이터를 생성해줍니다.
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',
},
},
}<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"
/>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',
},
],
},
}<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"
/>알아두면 좋은 정보:
msapplication-*메타 태그는 더 이상 Microsoft Edge의 크로미움 빌드에서 지원되지 않으며, 따라서 더 이상 필요하지 않습니다.
themeColor
폐기됨:
metadata의themeColor옵션은 Next.js 14부터 폐기되었습니다. 대신viewport구성을 사용하세요.
manifest
웹 애플리케이션 매니페스트 사양 (opens in a new tab)에 정의된 웹 애플리케이션 매니페스트입니다.
export const metadata = {
manifest: 'https://nextjs.org/manifest.json',
}<link rel="manifest" href="https://nextjs.org/manifest.json" />twitter
트위터 사양은 (놀랍게도) X(이전 트위터)뿐만 아니라 다른 곳에서도 사용됩니다.
트위터 카드 마크업 참조 (opens in a new tab)에서 자세히 알아보세요.
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'], // 반드시 절대 URL이어야 함
},
}<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:site:id" content="1467726470533754880" />
<meta
name="twitter:creator"
content="@next
js"
/>
<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" />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',
},
},
},
}<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
폐기됨:
metadata의viewport옵션은 Next.js 14부터 폐기되었습니다. 대신viewport구성을 사용하세요.
verification
export const metadata = {
verification: {
google: 'google',
yandex: 'yandex',
yahoo: 'yahoo',
other: {
me: ['my-email', 'my-link'],
},
},
}<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
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)',
},
],
},
}<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
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',
},
},
}<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"
/>appLinks
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,
},
},
}<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
기록물, 문서 또는 기타 자료의 컬렉션을 설명합니다 (출처 (opens in a new tab)).
export const metadata = {
archives: ['https://nextjs.org/13'],
}<link rel="archives" href="https://nextjs.org/13" />assets
export const metadata = {
assets: ['https://nextjs.org/assets'],
}<link rel="assets" href="https://nextjs.org/assets" />bookmarks
export const metadata = {
bookmarks: ['https://nextjs.org/13'],
}<link rel="bookmarks" href="https://nextjs.org/13" />category
export const metadata = {
category: 'technology',
}<meta name="category" content="technology" />facebook
Facebook 소셜 플러그인에 특정 Facebook 앱 또는 계정을 연결할 수 있습니다. Facebook 문서 (opens in a new tab)
알아두면 좋은 정보: appId 또는 admins를 지정할 수 있지만, 둘 다 지정할 수는 없습니다.
export const metadata = {
facebook: {
appId: '12345678',
},
}<meta property="fb:app_id" content="12345678" />export const metadata = {
facebook: {
admins: '12345678',
},
}<meta property="fb:admins" content="12345678" />여러 개의 fb:admins 메타 태그를 생성하려면 배열 값을 사용할 수 있습니다.
export const metadata = {
facebook: {
admins: ['
12345678', '87654321'],
},
}<meta property="fb:admins" content="12345678" />
<meta property="fb:admins" content="87654321" />other
모든 메타데이터 옵션은 내장 지원을 통해 다뤄져야 합니다. 그러나 사이트에 특정한 사용자 정의 메타데이터 태그나 새로 릴리스된 메타데이터 태그가 있을 수 있습니다. other 옵션을 사용하여 사용자 정의 메타데이터 태그를 렌더링할 수 있습니다.
export const metadata = {
other: {
custom: 'meta',
},
}<meta name="custom" content="meta" />같은 키 메타 태그를 여러 개 생성하려면 배열 값을 사용할 수 있습니다.
export const metadata = {
other: {
custom: ['meta1', 'meta2'],
},
}<meta name="custom" content="meta1" /> <meta name="custom" content="meta2" />지원되지 않는 메타데이터
다음 메타데이터 유형은 현재 내장 지원이 없습니다. 그러나 레이아웃 또는 페이지 자체에서 여전히 렌더링할 수 있습니다.
| 메타데이터 | 권장 사항 |
|---|---|
<meta http-equiv="..."> | redirect(), 미들웨어, 보안 헤더를 통해 적절한 HTTP 헤더를 사용하세요. |
<base> | 레이아웃 또는 페이지 자체에서 태그를 렌더링하세요. |
<noscript> | 레이아웃 또는 페이지 자체에서 태그를 렌더링하세요. |
<style> | Next.js에서 스타일링하는 방법을 알아보세요. |
<script> | 스크립트 사용 방법을 알아보세요. |
<link rel="stylesheet" /> | 레이아웃 또는 페이지 자체에서 스타일시트를 직접 import하세요. |
<link rel="preload /> | ReactDOM preload 메서드를 사용하세요. |
<link rel="preconnect" /> | ReactDOM preconnect 메서드를 사용하세요. |
<link rel="dns-prefetch" /> | ReactDOM prefetchDNS 메서드를 사용하세요. |
리소스 힌트
<link> 요소에는 브라우저가 외부 리소스가 필요할 가능성이 높다는 것을 암시할 수 있는 여러 rel 키워드가 있습니다. 브라우저는 이 정보를 사용하여 키워드에 따라 사전 로드 최적화를 적용합니다.
메타데이터 API는 이러한 힌트를 직접 지원하지 않지만, 새로운 ReactDOM 메서드 (opens in a new tab)를 사용하여 문서의 <head>에 안전하게 삽입할 수 있습니다.
'use client'
import ReactDOM from 'react-dom'
export function PreloadResources() {
ReactDOM.preload('...', { as: '...' })
ReactDOM.preconnect('...', { crossOrigin: '...' })
ReactDOM.prefetchDNS('...')
return '...'
}'use client'
import ReactDOM from 'react-dom'
export function PreloadResources() {
ReactDOM.preload('...', { as: '...' })
ReactDOM.preconnect('...', { crossOrigin: '...' })
ReactDOM.prefetchDNS('...')
return '...'
}<link rel="preload">
페이지 렌더링(브라우저) 수명 주기 초기에 리소스 로드를 시작합니다. MDN 문서 (opens in a new tab).
ReactDOM.preload(href: string, options: { as: string })<link rel="preload" href="..." as="..." /><link rel="preconnect">
원본으로의 연결을 사전에 시작합니다. MDN 문서 (opens in a new tab).
ReactDOM.preconnect(href: string, options?: { crossOrigin?: string })<link rel="preconnect" href="..." crossorigin /><link rel="dns-prefetch">
리소스가 요청되기 전에 도메인 이름을 해결하려고 시도합니다. MDN 문서 (opens in a new tab).
ReactDOM.prefetchDNS(href: string)<link rel="dns-prefetch" href="..." />알아두면 좋은 정보:
- 이러한 메서드는 현재 클라이언트 컴포넌트에서만 지원되며, 초기 페이지 로드 시 여전히 서버 사이드 렌더링이 됩니다.
- Next.js의 내장 기능인
next/font,next/image및next/script는 관련 리소스 힌트를 자동으로 처리합니다.
타입
메타데이터에 타입 안전성을 추가하려면 Metadata 타입을 사용할 수 있습니다. IDE에서 내장 TypeScript 플러그인을 사용하는 경우 수동으로 타입을 추가할 필요는 없지만, 원하는 경우 여전히 명시적으로 추가할 수 있습니다.
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',
}
}세그먼트 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) {}상위 메타데이터와 함께
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 | viewport, themeColor 및 colorScheme이 viewport 구성으로 대체되어 폐기되었습니다. |
v13.2.0 | metadata 및 generateMetadata 도입. |