SSR ํ๊ฒฝ (Next 13)์์ ๊ฐ๋ฐ์ ํ๋ค ๋ฌธ์ ๋ฅผ ๋ง๋ฌ์ด์.
next ๊ณต์ doc ๊ณผ ๊ตฌ๊ธ๋ง์ ํตํด ์ฌ๋ฌ ํด๊ฒฐ๋ฒ์ ์ฐธ๊ณ ํ์ฌ ํด๊ฒฐ ํ์ด์.
์๋ฌ ๋ด์ฉ์...
(Warning: Expected server HTML to contain a matching next js)
const [isClient, setIsClient] = useState(false);
useEffect(() => {
setIsClient(true);
}, []);
if(!isClient) return <div/>;
return (
...
๊ฐ์ ๋ก ํด๋ผ์ด์ธํธ์์ ์คํ ๋๋๋ก ํ๋ผ๋ ์ฝ๋์ธ๋ฐ ์ฌ์ค Next์์๋ use client
๋ผ๋ ๊ธฐ๋ฅ์ ์ ๊ณตํ๊ธฐ ๋๋ฌธ์ ํฐ ๋์์ด ๋์ง ๋ชปํ์ด์. ์ด๋ฏธ ํด๋น ํ์ผ์ ํฌํจ๋์ด ์๊ธฐ๋ ํ๊ตฌ์.
import dynamic from 'next/dynamic'
// ์๋ ์ฌ์ฉํ๋ ค ํ๋ ์ปดํฌ๋ํธ import
const NoSSR = dynamic(() => import('../components/no-ssr'), { ssr: false })
export default function Page() {
return (
<div>
<NoSSR />
</div>
)
}
๊ณต์ ๋ฌธ์๋ฅผ ํตํด dynamic์ผ๋ก ssr ์ปดํฌ๋ํธ๋ฅผ ๋นํ์ฑํ ํ๊ธฐ๋ก ํ์ด์. miss match ๋ฌธ์ ๋ ํด๊ฒฐ ํ๋ต๋๋ค. ๐ฅณ
ํ์ง๋ง... ๋ค๋ฅธ ์๋ฌ๊ฐ ๋ฐ์ํ์ด์..
(Warning: Extra attributes from the server: data-new-gr-c-s-check-loaded,data-gr-ext-installed)
๊ตฌ๊ธ๋ง์ ํตํด ์๋ฌ ์์ธ์ ์ฐพ์์ด์.
grammerly ๋ผ๋ ํฌ๋กฌ ํ์ฅ ํ๋ก๊ทธ๋จ ๋๋ฌธ์ด๋ผ๊ณ ํด์..
๋ต๋ณ๋ค์ ์ฐธ๊ณ ํ์ฌ suppressHydrationWarning=true
์ ๊ฐ์ ์์ ์ปดํฌ๋ํธ์ ์ต์
์ถ๊ฐ๋ฅผ ํ์ฌ ํด๊ฒฐ์ ํ์์ด์!
๊ทธ๋ฐ๋ฐ Hydration์ ๋ฌด์ํด๋ฒ๋ฆฌ๋ฉด ์ต์ ํ์ ์ข์ง์๋ค๋ ์๊ฒฌ์ด ์์ด ์ฉ ์ข์ง ์๋ค์. ๐
๊ตฌ๊ธ๋ง ์ค ๋ก์ปฌ์์๋ง ๋ฐ์ํ๋ค๋ ์๊ฒฌ๋ค์ด ์์์ด์. ๋ฐฐํฌ์๋ฒ๋ฅผ ํตํด ํ์ธํด๋ณด๋ ์ฌ์ค์ด๋๋ผ๊ตฌ์.
๊ทธ๋์ ์น ์ดํ๋ฆฌ์ผ์ด์
๋ชจ๋์ ๋ฐ๋ผ ๊ฐ์ ์กฐ์ ํ๊ธฐ๋ก ํ์ด์.
<body suppressHydrationWarning={process.env.NODE_ENV === 'development'}>
...
๋ค์๊ณผ ๊ฐ์ ๋น๋ ๋ชจ๋์ ๋ฐ๋ผ suppressHydrationWarning
๊ฐ์ด ๋ค์ด๊ฐ์.
์ด๋ ๊ฒ ์๋ฌ๋ ๊ต์ ํ๋ฉด์ ์ ๊ฐ ์ํ๋ ์ต์ ํ ๋ฌธ์ ๋ ์ด๋์ ๋๋ ํด๊ฒฐํ๋ฏ ํ๋ค์.