layout은 서로 상쇄되는 것이 아닌 상위 폴더의 layout과 하위 폴더의 layout이 중첩되어 렌더링 됨
1-4. route groups
route groups인 (home) 폴더 생성
폴더에 소괄호를 사용하여 이름을 묶어줌
이렇게 하면 url에 영향을 주지않음
프레임워크가 구분하지 못하게 함
2. Metadata
반드시 내보내야하는 object를 Metadata라고 함
<head> 태그는 Metadata를 찾고 해당 내용을 탭 title과 description으로 사용
// app/(home)/page.tsxexportconst metadata ={
title:"Home | Next Movies",};...// ----------------------------------------------// app/layout.tsxexportconst metadata ={
description:"The best movies on the best framework",};...
metadata는 필요한 페이지 혹은 레이아웃에 커스텀하여 사용할 수 있음
중첩된 레이아웃의 경우, metadata가 병합(merged)되어 표시됨
metadata는 내보내거나 가져와서 사용하는 것이 아니며, Sever 컴포넌트에서만 있을 수 있음 (Client 컴포넌트는 metadata 정의 안 됨)
2-1. metadata 템플릿
metadata의 특정 부분은 공통이고, 일부는 변경되는 경우가 있음
이 경우, 상위 layout에서 템플릿을 작성하고 변경되는 부분은 하위의 해당 layout 또는 page에서 작성
// 만약 home 페이지의 metadata의 title이 아래와 같고exportconst metadata ={
title:"Home | Next Movies",};// about-us 페이지의 metadata의 title이 아래와 같다면exportconst metadata ={
title:"About us | Next Movies",};
title에서 | Next Movies 앞 부문만 바뀌고 ”| Next Movies” 부분은 공통인 것을 볼 수 있음
이러한 상황에서 metadata의 템플릿을 사용할 수 있음
// 상위 layout에서 metadata 템플릿 적용// app/layout.tsximport{ Metadata }from"next";exportconst metadata: Metadata ={
title:{
template:"%s | Next Movies",default:"Next Movies.",},
description:"The best movies on the best framework",};// 하위 page, layout에서 변경되는 값 받기// app/(home)/page.tsxexportconst metadata ={
title:"Home",};// app/about-us/layout.tsxexportconst metadata ={
title:"About us",};
TypeScript의 경우, Next.js에서 제공하는 Metadata 타입을 사용
title에 객체로 template과 기본 값(default)을 넣어준다.
template에서 %s은 하위 page나 layout에서 title 문자열을 받고 그 외의 부분(”| Next Movies”)은 공통으로 작성됨
만약 title이 작성되지 않은 page나 layout에서는 기본 값이 출력됨
2-2. Dynamic Metadata - generateMetadata()
Home(index) 페이지, 소개 페이지(about-us)의 경우, 동적이지 않고 하나의 제목만 가지고 있음
하지만, 영화 디테일 페이지와 같은 경우, [id]에 따라 각각의 제목이 필요함
generateMetadata 함수를 사용하여 해결할 수 있음
// app/(movies)/movies/[id]/page.tsx...import{ getMovie }from"../../../../components/movie-info";interfaceIParams{
params:{ id:string};}exportasyncfunctiongenerateMetadata({ params:{ id },}: IParams){const movie =awaitgetMovie(id);return{
title: movie.title,}};...
프레임워크가 해당 함수를 찾아 metadata를 동적으로 적용해줌
따라서 export 해주어야 함
해당 함수에서 getMovie() 함수를 통해 데이터를 fetch하는데 movie-info 컴포넌트에서 역시도 getMovie() 함수를 사용하고 있어 속도가 느려질 수도 있다는 우려있을 수 있지만,
Next.js에서 fetch된 데이터를 캐싱하고 있어 속도에 문제없음