- [ ] Guides / Styling and Layouts → Styling components with CSS-in-JS frameworks
So, the [v2] ☂️ Umbrella issue for v2 docs has the above open TODO (although the issue has been closed); and this is also currently mentioned in the docs as "welcoming PRs".
I have some experience with the setup patterns for emotion (incl. v11) and styled-components here, and would like to help with this. As far as I can tell from the source, this would require additions to the Lifecycle APIs so that the serverEntry.js and clientEntry.ts files' rendering functions could be modified. I would need some guidance on creating these hooks.
Anyone want to help me get started?
Hi,
This is definitively something we should have, but is not so easy.
We also need to extract critical CSS to inline it in the pages.
It's already been mentioned somewhere that we may need to do something similar to how Gatsby works (docusaurus-browser/docusaurus-ssr files...).
I don't have much more infos to provide, this needs exploration :)
Maybe a good start would be to study all the css-in-js gatsby plugins, and maybe create some kind of doc/spreadsheet, to see what are the useful lifecycles / api surface to provide to make it possible to support a wide range of CSS-in-JS libraries.
Yes, off the top of my head the necessary operations for CSS-in-JS libs tend to be:
<App /> component with custom Providers which enable collection and critical extraction<head/> elements with those extracted styles, per pageastroturf and linaria: extend the webpack config with custom loadersThe latter 3 are all supported in Docusaurus in one way or another AFAICT; what's really missing is wrapping the <App /> element.
In Gatsby as I'm sure you know, this is done through the wrapRootElement and/or wrapBodyElement functions, which are exported from gatsby-ssr.js and gatsby-browser.js.
It seems to me, that these correspond to the serverEntry.js and clientEntry.ts files I mentioned above... so I'm thinking some plugin APIs like wrapServerRootElement and wrapClientRootElement, as long as they could also provide a way to set Head elements, would do the trick
Examples from Gatsby—note: many only require a babel plugin for the client side, and only modify rendering for the SSR part
@slorber on closer examination, after trying to hack this today: I'm guessing when you said "it's not so easy" you might have been thinking about react-loadable...? This scheme doesn't seem so far to be compatible with the HOCs that are needed for collecting CSS from the component tree
Thanks for the details @lunelson
I don't have time to investigate these things right now but we'll likely come back to it once i18n is there
Note, we might introduce a way to wrap root element in this PR: https://github.com/facebook/docusaurus/pull/3153
@slorber yes functions for wrapping root and/or page element would also solve https://github.com/facebook/docusaurus/issues/2891. I see that you've indicated it as low-priority, but IMO it's rather important, e.g. for components or context-providers that may be maintaining global state and doing async operations, such as an analytics consent-manager which is causing me trouble at the moment
@lunelson in the meantime alpha66 declare a new component "LayoutProviders" that you can swizzle and wrap with custom providers.
For minimum maintenance burden, you can also check this doc to "enhance" an existing theme comp without duplicating its code: https://v2.docusaurus.io/docs/using-themes/#wrapping-theme-components
But I understand the issue about stateful providers resetting their states. We'll try to solve this soon after I finish i18n.
Thanks for the tips @slorber, good to know about those new components, but indeed yes the remounting-on-route-change problem remains open