Next.js: How can I externalize the css to a separate file for browsers to cache?

Created on 22 Mar 2017  路  13Comments  路  Source: vercel/next.js

The default behavior is to inject all styles to the HTML in a style tag.
How can I make sure all styles are cached by browsers separately when I update my app?
Is there an example using extract-text-webpack-plugin in a next.config.js or is there another recommended way to achieve that?

Most helpful comment

@timneutkens Is there any official way to do load external CSS that works properly with browser caching (i.e. will output <style> tag that loads CSS file with webpack's revision hash in its filename), e.g. if someone already has all CSS in separate CSS/SASS/LESS files and doesn't want to port it all to CSS in JS just yet?

All 13 comments

add a plain old <link rel="stylesheet" type="text/css" href="style.css">?

You might find the example in nextjs-starter helpful.

In index.js it uses express to add a route like this:

```
// Add route to serve compiled SCSS from /assets/{build id}/main.css
const sassResult = sass.renderSync({file: './css/main.scss', outputStyle: 'compressed'})
server.get('/assets/:id/main.css', (req, res) => {
res.setHeader('Content-Type', 'text/css')
res.setHeader('Cache-Control', 'public, max-age=2592000')
res.setHeader('Expires', new Date(Date.now() + 2592000000).toUTCString())
res.send(sassResult.css)
})

The [header.js](https://github.com/iaincollins/nextjs-starter/blob/master/components/header.js) component of the web page then has something like this:

import Package from '../package'
let pathToCSS = '/assets/' + Package.version + '/main.css'
let stylesheet =
```

Of course you don't need express just do this but it just happens to as the rest of the example uses it.

The actual example is a bit more sophisticated as it also does inlining and live reloading in development mode and only adds it as a link in production, but you can see how that's done (with webpack config in next.config.js) in the example.

I am using a local scoped styled-components
I'm following the with-styled-components example
It results in a