v13.2
에 추가된 빌트인 기능head.js
파일 대체 (🔴 deprecated)import { Metadata } from 'next'
export const metadata: Metadata = {
title: 'NoowaH Blog',
description: 'Generated by create next app',
}
const page = () => {
return <div>NoowaH Blog</div>
}
export default page
more on : beta.nextjs.org | Metadata
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',
alternates: {},
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">
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',
},
};
<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" />
generateMetadata
라는 예약된 이름의 비동기 함수 사용Promise<Metadata>
export const generateMetadata = async ({ params }: any): Promise<Metadata> => {
return {
title: 'test',
description: params.slug,
}
}
const Page = ({ params }: any) => {
return <div>{params.slug}</div>
}
export default Page
fetch
fetch
API를 사용하게 될 경우 페이지 컴포넌트에서 비동기 함수를 요청하는 방식과 동일하게 호출fetch
API를 사용하게 될 경우, 호출된 비동기 함수가 동일한 함수라면 내부적으로 알아서 캐싱을 하여 중복 요청을 막음export const getData = async(id: string) => {
const res = await fetch(`endpoint/${string}`)
return res.json()
}
export const generateMetadata = async ({ params }: any): Promise<Metadata> =>
{
const data = await getData(params.id)
return {
title: data.title,
description: params.slug,
}
}
const Page = async ({ params }: any) => {
const data = await getData(params.id)
return <div>{params.id}</div>
}
export default Page
custom API
fetch
를 사용하지 않는 경우 getData()
를 cache()
로 감싸주면 해결 cache
로 감싸진 함수는 export
하여cache
: React 18의 빌트인 서스펜스 캐시const getData = cache(async (slug: string) => {
// custom api without fetch
})
export const generateMetadata = async ({ params }: any): Promise<Metadata> => {
const post = await getData(params.slug)
return {
title: post?.title,
}
}
const PostDetailPage = async ({ params }: any) => {
const post = await getData(params.slug)
return (
return post ? (
<div>{post.title}</div>
) : null
}
layouts.tsx
파일에서 하위 경로 페이지들이 동일하게 사용할 template
설정 가능/app/posts/layouts.tsx
import { Metadata } from 'next'
export const metadata: Metadata = {
title: {
default: 'Posts', // <title>Posts</title>
template: 'Posts | %s',
}
}
interface Params {
children: ReactNode
}
const layouts = ({ children }: Params) => {
return (
<div>{children}</div>
)
}
export default layouts
/app/posts/[slug]/page.tsx
import { Metadata } from 'next'
export const generateMetadata = async ({ params }: any): Promise<Metadata> => {
return {
title: params.slug, // <title>Posts | {slug}</title>
}
}
const page = ({ params }: any) => {
return <div>{params.slug}</div>
}
export default page