kriasoft / isomorphic-style-loader

CSS style loader for Webpack that is optimized for isomorphic (universal) web apps.
https://reactstarter.com
MIT License
1.27k stars 144 forks source link

What's the recommended approach for updating styles when client-side route updates #41

Closed grgur closed 8 years ago

grgur commented 8 years ago

Ok so let's say that our isomorphic app changes route and the client side router changed the view based on JavaScript. Is there an official approach to retrieving the CSS that was not already inserted in <head>?

In other words:

  1. User navigates to the web site.
  2. Server side renderer returns HTML + CSS with help from isomorphic-style-loader
  3. Server also returns the JS bundle used to render views on the client side (a-la SPA style)
  4. User wants to go to the Account page. Account link is clicked.
  5. Client side router changes view to Account.
  6. The Account page is rendered on the client side and shown

ok, here's my question

  1. How should I retrieve the CSS needed for the Account page to show?

One approach could be to use the ExtractTextPlugin, but that doesn't seem to work (because ExtractTextPlugin loader doesn't know how to call _getCss().

Any ideas?

Thanks a bunch

frenzzy commented 8 years ago

With React.js you can use the convenient decorator function withStyles(styles)(MyReactComponent), take a look at the docs and source code.

In your own framework, you must call the _insertCss and _getCss functions manually, example:

// frontend
import s from './PageStyles.css'
const removeCss = s._insertCss() // mount (create <style> DOM node)
removeCss()                      // unmount (remove <style> node from DOM)

// backend
import s from './PageStyles.css'
const response = s._getCss()     // css string
grgur commented 8 years ago

@frenzzy thanks a bunch for a quick answer.

Ok, so the way i see it - insertCss function basically gets CSS from the CSS module object (import s from './PageStyles.css'). That's great when it's on the server side, but how exactly do I fetch that CSS object if I'm already on the front-end? Obviously loader's css objects are kept on the server side, no? Does my question make sense?

frenzzy commented 8 years ago

You should use isomorphic-style-loader for both client-side and server-side bundles. Frontend uses _insertCss to mount styles to the DOM, backend uses _getCss to prepare html string which will be responded to the client-side. You can find a working example in React Starter Kit:

grgur commented 8 years ago

Ok so basically the thing i was interested in is how the rest of the css (besides critical path) is transferred to the client. Looks like it's bundled in JS.

Thanks

koistya commented 8 years ago

@grgur yep, it's bundled into JavaScript bundle (or chunks) and it's usually a good idea to load that bundle asynchronously, for example, in the <head> section of your HTML page:

<script async src="/bundle.js"></script>
grgur commented 8 years ago

Yes, exactly how i had it set up.

Thank you for open sourcing this. It's top notch!