preact-isomorphic-style-loader

CSS style loader for Webpack optimized for critical path CSS rendering and isomoprhic web apps

Usage no npm install needed!

<script type="module">
  import preactIsomorphicStyleLoader from 'https://cdn.skypack.dev/preact-isomorphic-style-loader';
</script>

README

Preact Isomorphic CSS style loader for Webpack

NPM version NPM downloads Library Size

CSS style loader for Webpack that works similarly to style-loader, but is optimized for critical path CSS rendering and also works great in the context of isomorphic apps. It provides two helper methods on to the styles object - ._insertCss() (injects CSS into the DOM) and ._getCss() (returns a CSS string).

See getting started  |  changelog  |  Join #react-starter-kit chat room on Gitter to stay up to date

How to Install

$ npm install preact-isomorphic-style-loader --save-dev

Getting Started

Webpack configuration:

module.exports = {
  /* ... */
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          'preact-isomorphic-style-loader',
          {
            loader: 'css-loader',
            options: {
              importLoaders: 1
            }
          },
          'postcss-loader'
        ]
      }
    ]
  }
  /* ... */
}

Note: Configuration is the same for both client-side and server-side bundles. For more information visit https://webpack.js.org/configuration/module/.

React component example:

/* App.css */
.root { padding: 10px }
.title { color: red }
/* App.js */
import { h } from 'preact'
import withStyles from 'preact-isomorphic-style-loader/withStyles'
import s from './App.scss'

// you can use decorator @withStyles(style) and export App
function App(props, context) {
  return (
    <div className={s.root}>
      <h1 className={s.title}>Hello, world!</h1>
    </div>
  )
}

export default withStyles(s)(App)

See server-side rendering example below:

import express from 'express'
import {h} from 'preact';
import render from 'preact-render-to-string';
import StyleContext from 'preact-isomorphic-style-loader/StyleContext'
import App from './App.js'

const server = express()
const port = process.env.PORT || 3000

// Server-side rendering of the React app
server.get('*', (req, res, next) => {
  const css = new Map()
  const insertCss = (styles) => styles.forEach(style => {
      const {id,css} = style._insertCss();
      isomorphicStyle.set(id, css)
  });
  const body = render(
    <StyleContext.Provider value={{ insertCss }}>
      <App />
    </StyleContext.Provider>
  )
  const html = `<!doctype html>
    <html>
      <head>
        <script src="client.js" defer></script>
        <style id="${id}">${css}</style>
      </head>
      <body>
        <div id="root">${body}</div>
      </body>
    </html>`
  res.status(200).send(html)
})

server.listen(port, () => {
  console.log(`Node.js app is running at http://localhost:${port}/`)
})