Applying global styles in Next.js

Viewed 16055

I am using Next.js with Typescript. The margin of the body is default 8px and I want to get it to 0px. When I try to add an external style sheet to my index.tsx file it throws an error that you can only add external stylesheet to _app.tsx. However, even when I try to import in my _app.tsx, it doesn't change the global style of the body. I am using Emotion css for the styling part. Is there a different way to change the style of the body in the index file using global style? Here is my index.tsx code and I have tried adding the global styles using Emotion CSS as well but it doesn't work.

class Index extends React.Component {
  render() {
    return (
      <div className='body'>
        <Container>
          <style jsx global>{`
            .body:global() {
              margin: 0px;
            }
          `}</style>
          <NavBar />
        </Container>
      </div>
    );
  }
}
4 Answers

You need some global styles (<style jsx global>) to style the body element or provide css resets.

Example:

import Link from "next/link";

export default () => (
  <div>

    <style jsx global>{`
      body {
        background-color: red;
      }
    `}</style>

    Hello, One!
    <Link href="/two">
      <a>Go to two</a>
    </Link>
  </div>
);

Code Sandbox

According to the official docs:

Global CSS cannot be used in files other than your Custom <App> due to its side-effects and ordering problems.

Possible Ways to Fix It

Relocate all Global CSS imports to your pages/_app.js file.


How to do this in your case?

Well, the best way is to use a CSS base, lets take normalize.css for example.

  1. Run yarn add normalize.css or npm i normalize.css, depending on whichever you are using.

  2. Add import 'normalize.css'; in each of the page you want to use the base on. Official Docs.

Well this could seem redundant if you want to use the base in all of your pages. If so, you can, alternatively, create a file page/_app.tsx (any of the extension .js,.jsx,.ts,.tsx will work) and put this in it:

import 'normalize.css';

export { default } from 'next/app';

Note : If your app is running and you just added a custom App, you'll need to restart the development server. Only required if pages/_app.tsx didn't exist before.

No need to worry about other caveats mentioned in the docs as we are simply re-exporting App without any modification.

There are many CSS bases available choose any that seems best for you.


If you want to add custom global styles, then follow this:

  1. Create a file styles/globals.css (.scss,.sass,etc. will also work if you have configured Next.js properly) and put your styles in that file.

  2. Now add an import in pages/_app.tsx.

import '../styles/globals.css'; // change extension from `.css` to
                                // whatever you created above

export { default } from 'next/app';

If you have already created a module path alias for ../styles, then you might wanna change the styles import statement (probably to something like import '@styles/globals.css').

Also, if you are using less/sass/scss and want to use a base at the same time along with your custom global styles you simply need to use an import statement in your stylesheet (no need to import the base in _app.tsx if imported in the global stylesheet). An example:

// file: styles/globals.scss
@import '../node_modules/normalize.css/normalize.css';

// your styles...
body {
  color: red;
}
// file: pages/_app.tsx
import '@styles/globals.scss';

export { default } from 'next/app';

Moreover, in your case it has not worked most probably because you were styling .body instead of body. It is likely that margin was present in the body, not your div.body.

This is how your _app.js, _app.tsx should look like; styles.css may have your CSS to reset the default browser properties, you can try adding other stylesheets here.

import '../styles/styles.css'

export default function App({ Component, pageProps }) {
   return <Component {...pageProps} />
}
Related