Next.js: Include css in a next project?

Created on 27 Nov 2016  ·  31Comments  ·  Source: vercel/next.js

I know that Next uses Glamor and css-in-js. But, is there any way to use real css/less/scss in a Next project...somehow? At least for bootstrapping a project?

My reasoning is this - for simple sites, such as the ones Next is targeted at, most pre-made html themes that can be bought online are made using pure html and css. So, all you need to do is chop up the HTML into react components, put them in the appropriate page folders, and you're done.

I would really love to use Next for my project, but if I am not able to somehow leverage ready-made css, it would be a deal breaker for me. Is there a solution or a workaround for this use case?

Most helpful comment

  • Create a /static folder at the same level the /pages folder.
  • In that folder put your .css files
  • In your page components import Head and add a <link /> to your CSS.
import React from 'react';
import Head from 'next/head';

export default () => (
  <div>
    <Head>
      <title>My styled page</title>
      <link href="/static/styles.css" rel="stylesheet" />
    </Head>
    <p className="some-class-name">
      Hello world!
    </p>
  </div>
)

And that's it, this way Next.js should render the link tag in the head of the page and the browser will download the CSS and apply it.

All 31 comments

  • Create a /static folder at the same level the /pages folder.
  • In that folder put your .css files
  • In your page components import Head and add a <link /> to your CSS.
import React from 'react';
import Head from 'next/head';

export default () => (
  <div>
    <Head>
      <title>My styled page</title>
      <link href="/static/styles.css" rel="stylesheet" />
    </Head>
    <p className="some-class-name">
      Hello world!
    </p>
  </div>
)

And that's it, this way Next.js should render the link tag in the head of the page and the browser will download the CSS and apply it.

Wow, thank you for the quick reply :). It works! There is just one snag - when first loading the page, there is a flash of the unstyled html just before everything is rendered properly. I am not sure if it's from css or js files loaded post-react. Would there be a workaround for this?

Anyway, I am absolutely impressed with the work you guys are doing and thank you again for the quick reply!

Nevermind, I imported the header component with the css and js links in the index page as well, and the flash is gone. Furthermore, changing the anchor tags to Link components, removes any leftover jumping. The downside is that the Link component seems to strip any html tags from its children (such as span tags with icon classes), so that only text is left.

I know this use case is the opposite of correct and optimized, but it is really useful for cases when we have to resort to quick and dirty...ugliness :)

So the workflow for integrating a pre-made html theme is this:

  1. create a static folder and copy/move all the js/css/img files from the template
  2. create a page.js file with a component
  3. Add the html to the component and modify it to comply with react
    3.1. add the Head tag and in it include all the css/js files from the original html
    3.2. update the path to those files to match the new static folder
    3.3. Copy/paste the html below the head tag
    3.4 Close or self-close any unclosed html tags (including link, input and img tags)
    3.5. Find/Replace all instances of class=" with className="
    3.6. Remove all html comments

@manolkalinov can you please append your code for easy reference? I know you wrote the workflow but a sample code make it easier to follow and debug if problem occurs.

Adding CSS in the head tag does work for sure. However it's kind of hacky and what if we want to use something like postcss or sass? How to convert existing css styles into glamor JSON object? It's also very difficult for designers to style the page by using glamor. There must be a better way of doing it.
By the way, compares to CSS Modules, what is the benifit of using glamor?

@andyhu please read https://github.com/zeit/next.js#faq about the benefit of using glamor.
About postcss or sass, customizing webpack config would allow you to use them (https://github.com/zeit/next.js/pull/222), or I think you can just compile these files to css before executing next.

I think it's solved. Feel free to reopen if you still have the problem. Thanks for your answer @sergiodxa !

@nkzawa I use customizing webpack config, so I can use less in my project.here is my code
next.config.js

/* eslint-disable */

export default {
    webpack: (webpackConfig) => {
        const newConfig = { ...webpackConfig };
        newConfig.module.preloaders.push({
            test: /\.less$/,
            loader:'style-loader!css-loader!less-loader'
        });
        return newConfig;
    },
    cdn: false
}

then I require the less file import './index.less', but error occurs

You may need an appropriate loader to handle this file type.
SyntaxError: Unexpected token (1:4)

I am sure I have installed less, less-loader, css-loader,style-loader, can you give some suggestion, thanks in advance.

You should try

config.module.rules.push({
      test: /\.less$/,
      use: [
        'style-loader',
        { loader: 'css-loader', options: { importLoaders: 1 } },
        'less-loader'
      ]
    })

@kimown Did you succeed importing the less file? If so, would you mind sharing how you did it?

@sergiodxa How can i import css from node_modules?

I had this question myself regarding importing CSS from an npm package.

E.g. rc-slider

import 'rc-slider/assets/index.css'

Was there an answer to this? @notrab

@notrab
Try this

In your root or _document component

import stylesheet from 'rc-slider/assets/index.css';

<div className='root'>
    <style dangerouslySetInnerHTML={{ __html: stylesheet }} />
    <Main />
</div>

@saadbinsaeed I tried this. It works for own components and pages. But I want to bundle it with webpack, instead of having it inline.

@schoenwaldnils I tried to do so but couldn't. As per my understanding we are using a server side application so we can not bundle the separate css files and send them to the client because server do not knows what css is. we have to embed the css in our html . To access it in your whole application embed it in root component or link it in header as shown above by @sergiodxa.

I have tried @sergiodxa approach, but it doesn't work for me. Is this still applicable with the latest versions of Next?

@sergiodxa thanks. Just I was looking for.

@sergiodxa You should change your answers. It's not statics! It must be static

Using CSS imports is simple now using https://github.com/zeit/next-plugins

Sorry for the 1-year-old issue bump. Apparently, people end up here through google.

Using CSS imports is simple now using https://github.com/zeit/next-plugins

Sorry for the 1-year-old issue bump. Apparently, people end up here through google.

Not really. I can't seem to find an easy way to import css directly from the node_module. Is this by design?

Using CSS imports is simple now using https://github.com/zeit/next-plugins
Sorry for the 1-year-old issue bump. Apparently, people end up here through google.

Not really. I can't seem to find an easy way to import css directly from the node_module. Is this by design?

Not really after the next version 7, do you already had a look? it's even more easier than before ;)

@mtrabelsi could you please give some example how do you import css directly from node module in Next.js 7 because I'm stuck with it. I need to import some styles from node module but I can't find worked solution.

We fixed this issue by using copy-webpack-plugin.
In webpack config (next.config.js):

config.plugins.push( new CopyWebpackPlugin([ { from: path.join(__dirname,'node_modules/react-datepicker/dist/react-datepicker.css'), to: path.join(__dirname, 'static/react-datepicker.css') } ]) );

you can checkout a fix for the client side css fix https://github.com/AmanAgarwal041/next-css-fix

I think that there is a simpler way to do it:

3 simple steps:

  1. Install next-css plugin:
npm install --save @zeit/next-css
  1. Create in your root directory next.config.js with the following content:
// next.config.js 
const withCSS = require('@zeit/next-css')

module.exports = withCSS({
  cssLoaderOptions: {
    url: false
  }
})
  1. Now you should be able to import styleshets from node_modules like this:
import 'bootstrap-css-only/css/bootstrap.min.css';

_Note: Using Next v 8+_

Background:
I spent a few hours trying to simply import a CSS installed as a node_module and the various solutions are mostly hacky workarounds, but as shown above, there is a simple solution.
It was provided by one of the core team members: https://spectrum.chat/next-js/general/ignoring-folders-files-specifically-fonts~4f68cfd5-d576-46b8-adc8-86e9d7ea0b1f

If anyone is using @sergiodxa's answer, if you name the folder static the link tag should reference be static.

😂 it seems people read GitHub issues more than official documentation (https://github.com/zeit/next-plugins/tree/master/packages/next-css) 😂

@mtrabelsi, This issue is more valuable than documentation imo, If you want to use css directly, e.g. import 'bootstrap-css-only/css/bootstrap.min.css';, there is nothing mention in the documentation until I found @Vrq 's answer

@timneutkens

I'm trying to just import my own normal css file. In the end is the correct way to import it using the documentation in https://github.com/zeit/next-plugins/tree/master/packages/next-css
or is the correct way using @sergiodxa answer from back in 2017, which imports through a link in the <Head> tag?

Here's what I've found on my end:

  • Both methods work when you load a page directly (go directly to the url)
  • Only Sergios way works for when you navigate to a page for the first time with Router.push (using the way from next-css documentation doesn't load the css)
  • Only problem with Sergio's way is that I still see the flash of unstyled html when going to a page for first time with Router.push

Any idea how to avoid this flash, without needing to include my css in the _document file?

Appreciate it.

See #8626 for CSS support coming to Next.js!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

kenji4569 picture kenji4569  ·  3Comments

knipferrc picture knipferrc  ·  3Comments

havefive picture havefive  ·  3Comments

renatorib picture renatorib  ·  3Comments

DvirSh picture DvirSh  ·  3Comments