Docusaurus: [v2] CSS-in-JS Rendering Hooks

Created on 7 Aug 2020  ·  9Comments  ·  Source: facebook/docusaurus

💥 Proposal: Hooks for CSS-in-JS Client and Server Rendering

  • [ ] 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?

advanced proposal

All 9 comments

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:

  • wrap the <App /> component with custom Providers which enable collection and critical extraction
  • set <head/> elements with those extracted styles, per page
  • extend the babel config, usually to provide a custom JSX function
  • ...and in the case of exctraction libs like astroturf and linaria: extend the webpack config with custom loaders

The 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

Was this page helpful?
0 / 5 - 0 ratings

Related issues

muuvmuuv picture muuvmuuv  ·  3Comments

chandankumar4 picture chandankumar4  ·  3Comments

MoogyG picture MoogyG  ·  3Comments

azu picture azu  ·  3Comments

ericnakagawa picture ericnakagawa  ·  3Comments