Next.js: Styled Components fail to SSR on first render

Created on 14 Feb 2018  路  14Comments  路  Source: vercel/next.js

I'm am using styled-components in Next.js. When I deploy the app, the first time the UI is rendered, it is unstyled. Only after a refresh does the SSR styles come through and persist.

Implementation based on:
https://github.com/zeit/next.js/tree/canary/examples/with-styled-components

_Anyone have ideas?_ I'm stumped atm :(
https://github.com/stephencorwin/nextjs-hello-world/tree/styled-components-ssr-error

  • [x] I have searched the issues of this repository and believe that this is not a duplicate.

Expected Behavior



When I deploy the app, any SSR styles should be rendered the first refresh.

Current Behavior



When I deploy the app, the first time the UI is rendered, it is unstyled. Only after a refresh does the SSR styles come through and persist.

First Render:
render-error

Second Render:
render-success

Steps to Reproduce (for bugs)


  1. Deploy to now
  2. Wait 2 mins for it to finish. Don't view the interstitial website with the progress status first.
  3. Go to the website generated by Now _-- fantastic feature btw!!!_
  4. My <Header />, <Footer />, and globalStyles() in the _document.js are not coming through.
  5. Refresh the page and you will notice the styling has been fixed.

Context



When I deploy the app, I should NOT have to visit the website once to ensure that the SSR styles are generated.

Your Environment


| Tech | Version |
|---------|---------|
|node|8.7.0|
|next|4.2.3|
|styled-components|3.1.6|
|babel-plugin-styled-components|1.5.0|
|OS|Windows 10|

Most helpful comment

+1. have the same problem at v8.0.1

All 14 comments

this is just a guess based on how the example (and my own project) is configured, but have you tried moving the global style injections out of _document?

I inject all of my global styles in a template component that i import into each page, and my getInitialProps in _document more or less just mirrors the example.

It's also worth noting that I always call injectGlobal _outside_ of getInitialProps, but I'm not smart enough on the SSR pipeline to speculate on if that matters or not.

So, in your case, try editing your Home.js to something like this

import React from 'react';
import Home from '../components/_templates/Home';
import globalStyles from '../styles/global-styles';

globalStyles();

export default () => <Home />;

I use this pattern a lot in my next app to inject third-party css on-demand, so I'm certain it works. Whether or not it addresses your specific problem is to be determinbed, though.

@brandonmp putting globalStyles() at the top of the file did solve the issue for styles injected via injectGlobal. I have updated the repository with the latest changes.

However, I am still having the same behavior for the <Header /> and <Footer /> components.

image

I don't think components in _document.js are handled normally in next. Try moving all components into <Main/>--ie, into the page component (Home or whatever). this means importing it into every page unfortunately, but it's not s bad.

from docs:

Note: React-components outside of

will not be initialised by the browser. If you need shared components in all your pages (like a menu or a toolbar), do not add application logic here

@brandonmp I was able to get it working by moving all of the components within <Main />.
https://github.com/stephencorwin/nextjs-hello-world/pull/3/files

It feels a little awkward though because in order to achieve my result of the StickyVerticalLayout (with scrolling Main), I now have to reference the #__next element whereas I didn't have to before.

html {
    overflow: hidden;
}

html,
body,
#__next {
    height: 100%;
}

Screenshots

Sticky Footer
image
Scrollable Main:
image

I would love to see this limitation of the custom document lifted in the future.

PR it! i've submitted a few PRs for nextjs docs before--it only takes a minute to do thru the github interface.

The hydration from styled-components is only done on the App component inside _document. That's the reason adding styled-components inside _document doesn't work normally.

@timneutkens I wound up here tonight with the same issues. With PR #4129 close to completion, does this mean we can / should do styled-components injectGlobal in the soon to be exposed app.js instead of _document.js and have it behave as expected?

This is quite an old issue now but I had the same problem.
I resolved it by implementing SSr for style-components following this example:
https://github.com/zeit/next.js/pull/5631

FYI this option removes the need to add {this.props.styleTags}

I just came here with the same problem. I copied the styled components example from the examples folder.

+1. have the same problem at v8.0.1

"I have the same problem" on a closed issue while not providing a reproduction is not really helpful. Can you open a new issue with a clear and concise reproduction following the issue template. Thanks 馃檹

same problem

@bel7aG

Read:

"I have the same problem" on a closed issue while not providing a reproduction is not really helpful. Can you open a new issue with a clear and concise reproduction following the issue template. Thanks 馃檹

And this whole thread: https://twitter.com/timneutkens/status/1154351052973625346

Was this page helpful?
0 / 5 - 0 ratings

Related issues

renatorib picture renatorib  路  3Comments

havefive picture havefive  路  3Comments

formula349 picture formula349  路  3Comments

timneutkens picture timneutkens  路  3Comments

pie6k picture pie6k  路  3Comments