문제 :
Warning: Prop `className` did not match.
Server: "sc-gikAfH eUPGCF" Client: "sc-bcXHqe wKDJu"
Next.js에서 styled-components를 사용하면 위와 같은 경고가 뜨곤 한다. 서버와 클라이언트의 클래스명이 다른 것이 원인이다.
Next.js는 첫 페이지 로드가 SSR로 동작하기 때문에, 서버에서 생성된 컴포넌트와 CSR로 클라이언트에서 생성된 컴포넌트의 클래스명이 서로 달라지게 된다.
해결방안 : next.config.js 에서 컴파일러에 styledComponents 를 설정해준다.
Next.js 12버전부터 babel 대신 swc를 사용하여 컴파일하도록 변경되었다.
만약 .babelrc가 있다면 babel을 사용하게 되므로 babelrc를 제거해야한다.
그리고 나서 next.config.js에서 nextConfig에 styledComponents 설정만 해주면 swc를 사용하면서 동일하게 문제를 해결할 수 있다.
/** @type {import('next').NextConfig} */
const nextConfig = {
compiler: {
styledComponents: true,
},
};
module.exports = nextConfig;
[참고] 기존 방식(.babelrc에서 plugin 설정)
yarn add -D babel-plugin-styled-components
.babelrc 파일에 아래와 같이 작성하면 된다.
{
"plugins": ["babel-plugin-styled-components"]
}
만약 CNA(create-next-app)을 사용하고 있다면, 루트 디렉토리에 .babelrc 파일을 만들고 아래와 같이 작성하면 된다.
{
"presets": ["next/babel"],
"plugins": ["babel-plugin-styled-components"]
}
아래와 같이 babel-plugin-styled-components에 추가적인 설정을 할 수 있다.
{
"presets": ["next/babel"],
"plugins": [
[
"babel-plugin-styled-components",
{
"ssr": true, // SSR을 위한 설정
"displayName": true, // 클래스명에 컴포넌트 이름을 붙임
"pure": true // dead code elimination (사용되지 않는 속성 제거)
}
]
]
}