Next.js: Unexpected flash of unstyled content when using with styled-components

Created on 2 Nov 2016  路  8Comments  路  Source: vercel/next.js

I am attempting to use next.js with styled-components. I've been noticing that although it works, I get a pretty large flash of unstyled content. I know next.js recommends glamor syntax but was thinking that this might be common for people coming from next who might be hoping to bring another method of styling their components. I am opening an issue with styled-components too since I am not actually able to determine where the issue is coming from.

Here is my example repo that shows the FOUC when using next and sc together:

https://github.com/jimthedev/next-styled-components-fouc

Tweet for reference: https://twitter.com/JimTheDev/status/792849817907007488
Corresponding styled-components issue: https://github.com/styled-components/styled-components/issues/162

Most helpful comment

@jimthedev I found a way to workaround the flashing issue thanks to the discussion here https://github.com/styled-components/styled-components/issues/124
(Note that this workaround will probably be obsolete once #251 Lands)

In your page component add the following import:

import styleSheet from 'styled-components/lib/models/StyleSheet'

Then on your render method:

render() {
    //This should only happen during the initial server render
    //Provide a boolean in getInitialProps to check if we are rendering on the server side
    const styles = (this.props.isServer)
      ? styleSheet.rules().map(rule => rule.cssText).join('\n')
      : null;
    return (
      <div>
        <Head>
          <style>
            { styles }
          </style>
        </Head>
        //Other stuff in there
      </div>
    );
  }

All 8 comments

following up with this, is this a problem with next or styled-components?

so its more of next.js favoring glamor @threepointone ?

P.S. Love your work!

edit: maybe this? https://github.com/zeit/next.js/blob/master/lib/css.js

@jimthedev I found a way to workaround the flashing issue thanks to the discussion here https://github.com/styled-components/styled-components/issues/124
(Note that this workaround will probably be obsolete once #251 Lands)

In your page component add the following import:

import styleSheet from 'styled-components/lib/models/StyleSheet'

Then on your render method:

render() {
    //This should only happen during the initial server render
    //Provide a boolean in getInitialProps to check if we are rendering on the server side
    const styles = (this.props.isServer)
      ? styleSheet.rules().map(rule => rule.cssText).join('\n')
      : null;
    return (
      <div>
        <Head>
          <style>
            { styles }
          </style>
        </Head>
        //Other stuff in there
      </div>
    );
  }

you can create a custom Headr element

import Head from 'next/head'

const Headr = (props) => {
  if (!process.env.browser) {
    let styles =
      <style>
        { styleSheet.rules().map(rule => rule.cssText).join('\n') }
      </style>
    props.children = props.children || []
    props.children.push(styles)
  }
  return <Head {...props} />
}

export default Headr

Perhaps we don't need styled components if we can use https://github.com/zeit/styled-jsx. Curious if styled-jsx was developed in part to respond to this issue.

@fdidron your solution works for me but it does require me to reload twice before the style shows up. I guess the first render styled-components is not aware of all the styles that should be applied. How did you go about working around that problem?

251 is here and we also have an example for styled-components https://github.com/zeit/next.js/tree/master/examples/with-styled-components

Was this page helpful?
0 / 5 - 0 ratings

Related issues

DvirSh picture DvirSh  路  3Comments

irrigator picture irrigator  路  3Comments

flybayer picture flybayer  路  3Comments

knipferrc picture knipferrc  路  3Comments

jesselee34 picture jesselee34  路  3Comments