[미해결] NextJs 사용중 SSR에서 styled-component가 깨지는 문제(dynamic import 사용)

마데슾 : My Dev Space·2021년 4월 27일
1

이슈

목록 보기
3/3

nextjs를 사용하여 서비스를 구축하였고 styled-component를 사용하여 스타일을 입혀주고있습니다.
그런데 프로필 페이지에서 SSR인 경우에 css를 가져오지 못해 css가 적용되지 않은 기본 html을 보여줍니다.. 그래서 유저 경험이 매우 좋지 않습니다..

function Profile() { 

  return (
    <>
      <ProfileContainer />
    </>
  );
}

문제를 해결하기위해 구글링을 하던중..

SSR인 경우에 nextjs에서 스타일 정보(styled-components)를 포함하지 않은채 렌더링되기 때문이라는 글을 발견하였고,
공식문서를 찾아보니 아래와 같은 글을 발견하였습니다.

Basically you need to add a custom pages/_document.js (if you don't have one). Then copy the logic for styled-components to inject the server side rendered styles into the .
Refer to our example in the Next.js repo for an up-to-date usage example.

nextjs 저장소에 있는 documnet.js를 따라서 해보았지만

static async getInitalProps(ctx) {
    const sheet = new ServerStyleSheet();
    const originalRenderPage = ctx.renderPage;
    try {
      ctx.renderPage = () =>
        originalRenderPage({
          enhanceApp: App => props => sheet.collectStyles(<App {...props} />),
        });
      const initialProps = await Document.getInitialProps(ctx);
      return {
        ...initialProps,
        styles: (
          <>
            {initialProps.styles}
            {sheet.getStyleElement()}
          </>
        ),
      };
    } catch (error) {
      console.error(error);
    } finally {
      sheet.seal();
    }
  }

여전히.. SSR에서 styled-component 로 만든 컴포넌트에 css가 적용되지 않습니다...

그래서 dynamic import를 사용하여 문제를 해결해보았습니다.

const ProfileContainer = dynamic(() => import('../features/user/profile/ProfileContainer'), {
  loading: () => <ModalLoadingComponent />,
  ssr: false,
});
  
function Profile() { 

  return (
    <>
      <ProfileContainer />
    </>
  );
}

SSR일때는 로딩컴포넌트를 보여주고 SSR이 끝나면 프로필 페이지에 보여야하는 컴포넌트를 보여주는 방식으로 변경하니.. 일단 크게크게 깨지는 것을 사용자에게 보여주는 문제는 해결하였지만... 로딩바 역시 스타일드 컴포넌트이기때문에 SSR일때 잠깐 깨집니다.. 여러 컴포넌트가 깨지는 것보다 하나의 로딩 컴포넌트만 꺠지는 것이 그래도 더 나을것이라 생각하여 이렇게 문제를 해결했(?)지만...


아주 정말 잠깐.. 0.03초?.. 정도...? 보였다가 아래처럼 예쁘게 나옵니다...

저 로딩 아이콘은 antd라는 라이브러리에서 제공해주는 것인데..
antd에서 가져온 컴포넌트들은 SSR에서 잘 나오더라구요... 😅

이렇게 해결하는게 맞는건가 싶네요... ㅎㅎ...
SSR인 경우에 nextjs에서 스타일 정보(styled-components) 포함한채로 렌더링이 되려면 어떻게 해야하는지 계속해서 찾아봐야겠습니다...

혹시 방법을 아시는분은 댓글을 꼬옥.... 남겨주시길 바랍니다 🥲
도와주세요 🥲

참고글

profile
👩🏻‍💻 🚀

6개의 댓글

comment-user-thumbnail
2021년 4월 28일

안녕하세요! 전 아래 링크보고 따라했더니 바로 적용됐어요. typescript로 구현한거라 좀 다르긴 하지만 혹시 다르게 하신 부분있으시다면 참고해보세요!
https://velog.io/@jeff0720/Next.js-%EA%B0%9C%EB%85%90-%EC%9D%B4%ED%95%B4-%EB%B6%80%ED%84%B0-%EC%8B%A4%EC%8A%B5%EA%B9%8C%EC%A7%80-%ED%95%B4%EB%B3%B4%EB%8A%94-SSR-%ED%99%98%EA%B2%BD-%EA%B5%AC%EC%B6%95

1개의 답글
comment-user-thumbnail
2021년 6월 30일

next.js에서 @emotions/styled를 한번 써보세요

1개의 답글
comment-user-thumbnail
2021년 7월 28일

next config 설정 바꾸세용

1개의 답글