4

I'm trying to apply global styles by importing .scss files in _app.js for a Nextjs app.

But the issue is, styles are not getting pre-applied on page load. Because of which FOUC happens for all the initial page render.

Example 1

Given below is a basic version of the issue mentioned above:

Project structure:

pages/
    _app.js
    index.js
app.scss
package.json

index.js file:

export default function Home() {
  return (
    <div className="hello">
      <p>Hello World</p>
    </div>
  );
}

_app.js file:

import "../app.scss";

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

app.scss file:

 $color: red;

 .hello {
     background-color: lavender;
     padding: 100px;
     text-align: center;
     transition: 100ms ease-in background;

     &:hover {
         color: $color;
     }
 }

package.json file:

{
  "name": "basic-css",
  "version": "1.0.0",
  "scripts": {
    "dev": "next",
    "build": "next build",
    "start": "next start"
  },
  "dependencies": {
    "next": "^9.4.5-canary.31", // using canary build as per https://github.com/vercel/next.js/issues/11195
    "node-sass": "4.14.1",
    "react": "^16.13.1",
    "react-dom": "^16.13.1"
  },
  "license": "ISC"
}

Example 2 (repo using next-sass)

As per the 3rd point of @Ramakay's answer Which creates a static hashed css file and appends it to <head/> tag but still the issue persists.


What I am expecting:

enter image description here

What I'm getting now:

enter image description here

I'm not using any external library like "styled-components" etc. And I'm not looking for it.

What can I do to fix the issue at hand?

boop_the_snoot
  • 3,209
  • 4
  • 33
  • 44
  • Have you ever been able to resolve this issue? It still persists in current versions of NextJS. – Matija Mrkaic Jun 25 '21 at 13:49
  • @MatijaMrkaic I started using styled-components. – boop_the_snoot Jun 26 '21 at 04:40
  • Hey, this is not actually FOUC, but the browser will download the CSS as a render blocking resource (see the second request) and will apply those styles before rendering the content on the browser. This is how webpages (traditionally) work. – Olavi May 09 '22 at 11:37

2 Answers2

0

Because this is a CSS in JS approach, the files are not rendered on the server side for the document pre-parser to apply so it has to wait for Javascript to download

  1. You can use the Nextjs offering - https://github.com/vercel/styled-jsx - which will output styles server as well as client side.
  2. You can look at exporting the SCSS separately and linking to the document head.
  3. Next-sass with Node-sass outputting a file - https://github.com/vercel/next-plugins/tree/master/packages/next-sass + https://github.com/sass/node-sass#outfile
Ramakay
  • 2,919
  • 1
  • 5
  • 21
  • I have added another option `next-sass` which seems to do it all as you like. I can see you use `node-sass` but it should be easy to replace it with `next-sass` which per the package documentation will extract the CSS and link it in your document head. You can still approach it with `node-sass` - If so, create a custom webpack config via `next.config.js` and use the approach detailed here https://florianbrinkmann.com/en/sass-webpack-4240/ Hopefully it helps, Options 3 is my preferred approach. – Ramakay Jul 10 '20 at 18:29
  • Check my updated question (Example 2). I tried 3rd option also, but it didn't work either. Styles are present in

    but they are not loaded along with the page request.

    – boop_the_snoot Jul 10 '20 at 19:35
  • Correct, i see that - Here is a sandbox https://codesandbox.io/s/github/raulsrule/fouc?file=/styles/app.scss ( thanks for trying thus far ) You can see that the styles for H1 are not output on the html source - https://ce1tm.sse.codesandbox.io/ If you want to continue down that path, you can have `node-sass` output a css file - https://github.com/sass/node-sass#outfile which you can write to disk and then link it in the document. `node-sass` options can be passed via the `next-sass` interface https://github.com/vercel/next-plugins/tree/master/packages/next-sass#with-sass-loader-options – Ramakay Jul 10 '20 at 20:30
  • somehow I was not able to do what u suggested in the last comment above – boop_the_snoot Jul 12 '20 at 07:55
  • @boop_the_snoot did you figure out a solution for this? – insivika Aug 04 '20 at 00:39
  • @insivika didn't find any native solution for this. StyledComponents provide a `ServerSideSheet` solution which does what I'm looking for. But I wanted a solution using Nextjs only. if you've got any, pls post it over here or point me to it, that'd be a great help. – boop_the_snoot Aug 04 '20 at 03:16
  • @boop_the_snoot I tested using Next.js' styled JSX and it seems to work however I'm most likely going to go with StyledComponent as that's a more universal tool. – insivika Aug 04 '20 at 15:58
0

enter image description here

This hack worked for me!!

For the next.js - you need to open _document.js and add a <script>0</script> just after body tag.

I read it here stackoverflow