SSR(Server Side Rendering)의 가장 큰 장점 중에 하나는 바로 SEO(Search Engine Optimization)이다. 다양한 SEO 스킬들을 적용하기 위해서 서버로부터 <head>
를 받을 수 있어야 한다. 이를 가능하도록 하는 것이 Next/Head
이다. 별다른 서버 작업을 하지 않아도 head
tag를 받을 수 있게 도와준다.
공식 문서에 따르면 다음과 같이 사용하면 된다. 일반 컴포넌트에 next/head
만 임포트 시키면 된다.
import Head from 'next/head';
const Index = (props) => {
return (
<>
<Head>
<title>인덱스</title>
<meta name="description" content="인덱스 페이지입니다." />
</Head>
<div>여긴 인덱스 페이지입니다.</div>
</>
);
};
export default Index;
위와 같이 인덱스 페이지를 구성하면 다음과 같이 서버에서 보내준다.
<html>
<head>
<title>인덱스</title>
<meta name="description" content="인덱스 페이지입니다." />
<meta name="next-head-count" content="4" />
</head>
<body>
<div id="__next">
<div>여긴 인덱스 페이지입니다.</div>
</div>
</body>
</html>
아래의 공식문서를 참고하면 된다.
https://nextjs.org/docs/api-reference/next/head
next/head
가 2개 들어 있을 때동일한 head에 동일한 tag가 들어가 있을 때, 어떻게 작동할까?
import Head from 'next/head';
import Link from 'next/link';
const Index = (props) => {
return (
<>
<Head>
<title>어바웃</title>
<meta name="description" content="어바웃 페이지입니다." />
</Head>
<Head>
<title>어바웃2</title>
<meta name="description" content="어바웃2 페이지입니다." />
</Head>
<div>여긴 어바웃 페이지입니다.</div>
<Link href = "/">
<div>index page로 이동</div>
</Link>
</>
);
};
export default Index;
위와 같이 어바웃, 어바웃2를 함께 사용하게 되면 동일한 태그를 기준으로 뒤에 페이지로 덮어씌워진다. 결과물은 다음과 같다.
<html>
<head>
<title>어바웃2</title>
<meta name="description" content="어바웃2 페이지입니다." />
<meta name="next-head-count" content="4" />
</head>
<body>
<div id="__next">
<div>여긴 인덱스 페이지입니다.</div>
</div>
</body>
</html>
next/head
말고도 html 레이아웃을 정해주는 _document.jsx도 있다. 설명은 공식문서로 대체한다.
https://nextjs.org/docs/advanced-features/custom-document
레이아웃을 정해주긴하지만 head를 직접 등록할 수도 있다.
// ./pages/_document.js
import Document, { Html, Head, Main, NextScript } from 'next/document'
class MyDocument extends Document {
render() {
console.log('document render');
return (
<Html>
<Head>
<title>도큐먼트</title>
<meta name="description" content="도큐먼트 페이지입니다." />
</Head>
<body>
<Main />
<NextScript />
</body>
</Html>
)
}
}
export default MyDocument
위와 같이 작성하고 나머지 페이지에 head는 그대로 둔다면 어떤 head가 위주가 될까?
결과물은 다음과 같다.
<head>
<title>도큐먼트</title>
<meta name="description" content="도큐먼트 페이지입니다." />
<title>어바웃2</title>
<meta name="description" content="어바웃2 페이지입니다." />
<meta name="next-head-count" content="4" />
</head>
두 태그가 동시에 생성된다. 같은 head 이지만 서로 다른 일을 하는 아이들인거 같다. 더불어 콘솔 창에는 에러 메시지가 떴다.
<title> should not be used in _document.js's <Head>. https://err.sh/next.js/no-document-title
타이틀 태그는 document에서 사용하지 말라는 뜻이다. 찾아본 결과에 따르면 _document.js에 있는 head는 실제 head 태그를 감싸는 역할만을 한다고 한다. 실제 head와 동일한 작업을 하는 것은 next/head
이다. 따라서 document.js에 있는 head는 특별한 경우가 아니면 사용하지 않아도 될 것 같다.
각 페이지별로 Head를 적용하면 어느 페이지든 각각 페이지에 맞는 Head를 적용할 수 있다. 더 쉽게 Head를 적용하기 위해 Hoc(Higher-order-component)을 이용해보자.
// ./components/hoc/withHead.js
import Head from 'next/head';
const withHead = (Component, title, description) => {
const C = props => {
return (
<>
<Head>
<title>{title}</title>
<meta name="description" content={description} />
</Head>
<Component {...props}/>
</>
);
};
return C;
};
export default withHead;
// ./pages/about.js
import Head from 'next/head';
import Link from 'next/link';
import withHead from '../components/hoc/withHead';
const Index = (props) => {
return (
<>
<div>여긴 어바웃 페이지입니다.</div>
<Link href = "/">
<div>index page로 이동</div>
</Link>
</>
);
};
export default withHead(Index, '어바웃', '어바웃 페이지입니다.');
위와 같이 작성하면 어떤 페이지라도 withHead만 적용하여 title과 meta tag를 적용할 수 있다.
_document.js
의 head 용법을 더 알아보아야 한다.이번에 head에 대해 알아보게된 계기가, 각 페이지마다 다이나믹하게 타이틀과 태그들을 바꾸어야 하는 상황이 있어서다. 기존에는 공통 태그를 적용하고 변경하지 않았는데, 변경하려고 보니, next/head에 대해 알게 되었고 hoc 적용에 대해서도 경험을 하게 되었다. 역시 작은 변화도 큰 경험을 하게 되는 것 같다. 귀찮다고 넘어가지 말고 알아보자.
By Cyrano on MAR 3, 2020.