For styled-components @geelen has worked on a new StyleSheetManager provider that allows the library to be used with both asynchronous and synchronous rendering. It also introduces style rehydration on the client side.
The problem we ran into with next.js is, that it's not possible to wrap the entire App in our provider and then inject the generated CSS into the head.
We found a workaround that needs us to wrap every page, and inject the styles in style tags in the body, which is obviously not that nice. Is there any plan to support wrapping the entire app, for every page, while still being able to manipulate the head at the same time on the server side?
Our API for this will look sth like this:
const sheet = new ServerStyleSheet()
const html = renderToString(sheet.collectStyles(<Example/>))
const css = sheet.getStyleTags()
Where sheet.collectStyles wraps that element in our provider.
The PR for the new stylesheet on the SC repo: https://github.com/styled-components/styled-components/pull/679
@philpl What do you think of this proposal:
export default class MyDocument extends Document {
static getInitialProps ({ renderPage }) {
const sheet = new ServerStyleSheet()
const {html, head} = renderPage(sheet.collectStyles)
const styles = sheet.getStyleTags()
return { html, head, styles }
}
render () {
return (
<html>
<Head>
<style>{this.props.styles}</style>
</Head>
<body>
<Main />
<NextScript />
</body>
</html>
)
}
}
This implies a change here:
https://github.com/zeit/next.js/pull/1776
@khankuan that would work. Sorry for the late reply
@khankuan @arunoda I tested this, and it does in fact work and solves our issue. Is this in line with how the API is supposed to look like? And if so, can this be released any time soon? :smile:
This actually seems to work now just fine. I'm not sure how we missed this :wink: https://sc-next-docs.philpl.com/docs/advanced#nextjs
Edit: Nope
Ah ok, how did you find that doc url :o
Sorry, I was mistaken. it doesn't actually work since Main just receives the html result, and doesn't actually render anything. I should get more familiar with how next.js works ;) https://github.com/zeit/next.js/blob/master/server/document.js#L92
@khankuan Those are the upcoming docs for Styled Components, that I'm currently working on
I think next.js renders App and Document on 2 different layers. So Document really only deals with the head and html.
@khankuan Yea, it seems like it 馃槮 So, your fix is still the only change that I could get this to work with :wink:
@philpl still doesn't work for me. can you share a repo or perhaps update the styled-components example?
Update: Works fine with @khankuan's suggestion
Update x2: I'm using styled's global injection and it seems to work without the fix for ssr
Someone recently made an update to the with-styled-components example. Could you check it? 馃憤
@timneutkens It looks like the example has indeed been updated to match the recommended workaround on our upcoming website: https://sc-next-docs.philpl.com/docs/advanced#server-side-rendering
It's still just a workaround though
It would be great if the renderPage function could take in an HOC, with the default set to identity. The HOC would wrap the page Component in render.js. That way, all pages could be enhanced across the board as needed.
Update: I submitted #2010
Thanks for the work guys.
Since we landed 3.0.1 with #2010, I hope we can close this.
If now, feel free to re-open or ping me.
Most helpful comment
Thanks for the work guys.
Since we landed
3.0.1with #2010, I hope we can close this.If now, feel free to re-open or ping me.