NextJs는 기본적으로 페이지를 SSR(서버사이드렌더링)한다. 서버에서 html 파일을 구성하여 브라우저 측에 전달해 렌더링한다.(CSS도) 이 후 JS 파일이 로드되어 자바스크립트 코드가 적용된다.
자바스크립트 코드가 적용되지 않는 페이지가 미리 렌더링 되기 때문에 CSS-in-JS
로 스타일링 하면 스타일이 적용되지 않는 html 코드가 먼저 렌더링 되는 문제가 발생하게 된다.
NextJS는 이에 대한 해결책으로 html 파일에 CSS-in-JS 형식으로 작성된 스타일 요소들을 주입시켜서 뒤늦게 적용되는 문제를 해결한다. 바로 'renderPage'를 커스터마이징 하면 된다.
Note: This is advanced and only needed for libraries like CSS-in-JS to support server-side rendering. This is not needed for built-in styled-jsx support.
import Document, { Html, Head, Main, NextScript } from 'next/document'
class MyDocument extends Document {
static async getInitialProps(ctx) {
const originalRenderPage = ctx.renderPage
// Run the React rendering logic synchronously
ctx.renderPage = () =>
originalRenderPage({
// Useful for wrapping the whole react tree
enhanceApp: (App) => App,
// Useful for wrapping in a per-page basis
enhanceComponent: (Component) => Component,
})
// Run the parent `getInitialProps`, it now includes the custom `renderPage`
const initialProps = await Document.getInitialProps(ctx)
return initialProps
}
render() {
return (
<Html>
<Head />
<body>
<Main />
<NextScript />
</body>
</Html>
)
}
}
export default MyDocument
만약 TypeScript를 사용하고 있다면, ./pases/_document.tsx
에서 작업하면 된다.
NextJs에서 페이지를 접속할 때 SSR을 이용하고, 이동 시 CSR를 이용하여 렌더링한다. 이때 server와 client에서 생성하는 class 해시값이 달라 충돌로 인해 콘솔창에 에러가 뜬다.
해결방법으로 바벨을 설치하여 .babelrc
파일을 설정하면 된다.
yarn add babel-plugin-styled-components
// babelrc 파일
{
"presets": ["next/babel"],
"plugins": [
[
"styled-components",
{
"ssr": true,
"displayName": true,
"preprocess": true
}
]
]
}