
개발
SSR에서 CloudFlare의 이메일 난독화 사용할 때Hydration failed
현재 DNS로 CloudFlare와 호스팅으로 Vercel을 사용하고 있다. 그러던 중 초대하지 않은 손님이 갑자기 오셨는데 hydration failed이다.
hydration failed란 간단하게 말하면 서버에서 미리 렌더링을 해서 보내준 html 결과물과 클라이언트에서 렌더링 결과물이 다르단 것이다. 보통 이 에러는 클라이언트에만 저장되어 있는 상태들, 대표적으로 localstorage를 이용하다 제일 많이 발생하게 되는데 이렇게 되면 이미지, 글자, 아이콘, css 스타일 등이 의도와는 다르게 표시가 된다. 치명적 에러라는 소리.

해당 링크의 내용
- Hydration failed because the initial UI does not match what was rendered on the server.
- There was an error while hydrating. Because the error happened outside of a Suspense boundary, the entire root will switch to client rendering.
원인
이 이슈의 원인은 찾기가 꽤 힘들었다. 실제 운영하는 서버에서만 에러가 났고 개발서버에서는 에러가 나질 않는 것이였다. 애초에 hydration failed는 react, next.js 관련 에러라 생각하고 소스코드 내에서만 찾기도 했었다. store persist도 테마설정 관련해서만 사용하고 있었고 사용하는 부분을 다 찾아 봤지만 정석대로 작성이 되어 있었다. 문제가 없을거라 판단을 하고 운영서버에서 렌더링 된 html 코드와 클라이언트에서 렌더링 된 html을 비교 해보기 시작했다.

비교를 하던 중 CloudFlare가 간섭한 코드가 보였다. CloudFlare의 Email Address Obfuscation 기능으로 인해 변경 된 부분인데 이 부분에서 hydration faild가 발생할 것이라고 가정을 세우게 된다.
오류 해결법
CloudFlare에 가서 해당 도메인 설정중에 Email Address Obfuscation 기능을 끄면 된다.

다시 사이트에 접속을 해보니

이제 hydration faild가 나오지 않게 됐다.
정리하면 서버와 클라이언트 사이에 CloudFlare가 자리하고 있는데 서버에서 보낸걸 그대로 보내야 할 CloudFlare가 이메일을 난독화 해버려서 이 에러가 났던 것이였다.
CloudFlare, Vercel 둘 다 상당히 좋은 서비스를 제공하고 있어서 포기를 할 수 없으니 이메일 난독화 기능만 끄고 사용하면 될 거 같다.