티스토리 뷰
✅ 각 페이지에 SEO 설정하기
각 페이지 컴포넌트 return문 안에 Head태그를 사용해 title, meta 태그들을 작성할 수 있다.
import SearchableLayout from "@/components/searchable-layout";
// ...
import Head from "next/head";
export const getStaticProps = async () => {
// ...
};
export default function Home({ allBooks, recoBooks }: InferGetStaticPropsType<typeof getStaticProps>) {
return (
<>
<Head>
<title>한입북스</title>
<meta property="og:image" content="/thumbnail.png" />
<meta property="og:title" content="한입북스" />
<meta property="og:description" content="한입 북스에 등록된 도서들을 만나보세요" />
</Head>
<div className={style.container}>
// ...
</div>
</>
);
}
Home.getLayout = (page: ReactNode) => {
return <SearchableLayout>{page}</SearchableLayout>;
};
Head 컴포넌트를 import할 때 next/head와 next/document에서 불러올 수 있는데
next/document에서 불러오는 Head 컴포넌트는 _document.tsx 파일에서만 사용할 수 있는 컴포넌트이다.
각 페이지에서 메타태그 설정을 위해 Head 컴포넌트를 불러올 때는 next/head로부터 import해야한다.
✅ fallback 상태를 사용하는 페이지에서 주의할 점
동적인 경로를 가진 SSG 페이지에서 SEO를 적용할 때, 아래와 같이
페이지 컴포넌트의 return문에는 meta 태그를 넣어주었지만 fallback 상태일 때 반환하는 컴포넌트에는 SEO 설정이 없다고 가정해보자.
(아래 코드에서 return "로딩 중입니다..." 부분)
export const getStaticPaths = () => {
return {
// ...
fallback: true,
};
};
export const getStaticProps = async (context: GetStaticPropsContext) => {
// ...
};
export default function Page({ book }: InferGetStaticPropsType<typeof getStaticProps>) {
const router = useRouter();
if (router.isFallback) return "로딩 중입니다..."; // 이 부분이 fallback일때 보여지는 컴포넌트
if (!book) return "문제가 발생했습니다. 다시 시도하세요.";
const { id, title, subTitle, description, author, publisher, coverImgUrl } = book;
return (
<>
<Head>
<title>{title}</title>
<meta property="og:image" content={coverImgUrl} />
<meta property="og:title" content={title} />
</Head>
<div>
// ...
</div>
</>
);
}
그러면 빌드타임에 생성되지 않는 페이지에 접속한 경우 해당 페이지에서 처음 응답받은 html을 보면
아무 SEO도 적용되지 않은 상태로 페이지가 보내진 것을 확인할 수 있다.
Page 컴포넌트에 설정해준 meta태그들은 fallback 상태가 끝나고 나서야 추가된다.
하지만, 페이지가 fallback 상태에 있을 때도 기본적인 meta 태그들은 설정해놓는 것이 더 좋기 때문에
아래와 같이 fallback 상태일 때 리턴하는 컴포넌트에도 meta 태그가 적용되도록 코드를 수정해보자.
export const getStaticPaths = () => {
return {
// ...
fallback: true,
};
};
export const getStaticProps = async (context: GetStaticPropsContext) => {
// ...
};
export default function Page({ book }: InferGetStaticPropsType<typeof getStaticProps>) {
const router = useRouter();
// fallback 상태일 때
if (router.isFallback) {
return (
<>
<Head>
<title>한입북스</title>
<meta property="og:image" content="/thumbnail.png" />
<meta property="og:title" content="한입북스" />
<meta property="og:description" content="한입 북스에 등록된 도서들을 만나보세요" />
</Head>
<div>로딩 중입니다...</div>
</>
);
}
if (!book) return "문제가 발생했습니다. 다시 시도하세요."; // fallback이 끝났는데도 뭔가 데이터에 문제가 있어서 데이터를 받지 못했을 때
const { id, title, subTitle, description, author, publisher, coverImgUrl } = book;
return (
<>
<Head>
<title>{title}</title>
<meta property="og:image" content={coverImgUrl} />
<meta property="og:title" content={title} />
<meta property="og:description" content={description} />
</Head>
<div className={style.container}>
// ...
</div>
</>
);
}
참고자료
'개발공부 > ⬛ Next.js' 카테고리의 다른 글
[Next.js] App Router 방식으로 라우팅 설정하기 (0) | 2024.09.19 |
---|---|
[Next.js] Pages Router의 장단점 (3) | 2024.09.17 |
[Next.js] data fetching 및 사전 렌더링 방식 3가지 (Using Pages Router) (1) | 2024.09.11 |
[Next.js] Global Layout과 페이지별 레이아웃 적용하기 (Using Pages Router) (0) | 2024.09.10 |
[Next.js] 스타일링 (2) | 2024.09.07 |
프론트엔드 개발자 삐롱히의 개발 & 공부 기록 블로그