teteyi3241
teteyi3241

Reputation: 271

How to inject css to next.js page on ssr?

I am new to next js.

I have _app.tsx page:

import '../styles/antd.css'
import '../styles/globals.css'
import type { AppProps } from 'next/app' 

function MyApp({ Component, pageProps }: AppProps) {
  return (
    <> 
      <Component {...pageProps} /> 
    </>
  )
}

export default MyApp

Problem is that styles - import '../styles/antd.css' are loaded as a external request in production run /_next/static/css/fffc165f54adb267.css it mean that there is a one second blink lag during the styles loading. Is there any better way how to load styles in my base page? Without external request for styles?

Upvotes: 1

Views: 7456

Answers (3)

Artiphishle
Artiphishle

Reputation: 886

as you're using the _app.jsx (same for .tsx) you're in the pages/ directory, where you can simply load the CSS like you try, the point is, it will always be CSR not SSR.

You have to wrap your Component with a SSRProvider within pages/.

Many libraries have that, I suggest using the most popular from the Adobe team:

https://react-spectrum.adobe.com/react-aria/SSRProvider.html

Usage:

/* useIsSSR is not needed here, but I wanted to know you about it. It's a hook that returns (boolean) whether this is on serverside */ (false if browser). */
import {SSRProvider, useIsSSR} from 'react-aria'
import type { AppProps } from 'next/app'

import '../styles/antd.css'
import '../styles/globals.css'

function MyApp({ Component, pageProps }: AppProps) {
  return (
    <SSRProvider> 
      <Component {...pageProps} /> 
    </SSRProvider>
  )
}

export default MyApp


Anyway, IMO the app/ directory is pretty stable, so I suggest to consider switching, expect you're working for a very important 0% downtime project that affects thousands of users, even then, you could ensure reliability with adaquate testing.

Here an example of me using useIsSSR() hook. I want to you think about it twice, it's more for testing/debugging to me, as I try to write pure isomorphic code (if you have to switch back and fro in the same file, you might have an architectural issue... or my implementing the perfect world instead of talking about it perspective again.)

useOnServer.ts (hook)

import { useIsSSR } from "@react-aria/ssr";

export default function useOnServer() {
  const isServer = useIsSSR();

  console.log(isServer ? "Server" : "Client");
}

you will see the appropriate console.log's in server and client (isomorphic code runs both sides)

Upvotes: 0

Artiphishle
Artiphishle

Reputation: 886

I'm using Next.js 13, usually with pages/ but working only in the /app directory now. SSR works like a charm, but for the styling that is different: as soon as I remove "use client"; everything works but styles. I've just added them to the root layout, living at: /app/(pages)/layout.tsx where (pages) shouldn't be an issue, as it's ignored (just used to structure my folders)....oh!

Solution

// relevant part of 'next.config.js'
const path = require('path');

module.exports = {
  sassOptions: {
    includePaths: [path.join(__dirname, 'src/styles')],
  },
};

I've included styles before instead of pointing into the src directory.

The thing I've learnt: before SSR ("use client") it worked pointing into a wrong directory.

Rather hard to find, as I've imagined SRR/CSR paths can't be of any reason, maybe that's handled behind the scenes for CSR (code abstraction is great, if you are the one abstracting it^^)

What I've learnt in the longterm btw: always read and try to understand the code of the packages you're using in your project. It's not a blackbox and over time:

  • It improves your coding style, you see creative ways of problem solving from pro's all over the world
  • It makes you use the package in a more accurate/efficient way.

So if anyone struggles applying styles, .css or .scss/.sass (well any sort of pre/post processing I think) I could be of further help I suppose, just comment and I try to not miss it. Thanks.

https://beta.nextjs.org/docs/styling/sass

Upvotes: 0

tubstrr
tubstrr

Reputation: 1255

Next.JS's docs when talking about importing CSS states

In production, all CSS files will be automatically concatenated into a single minified .css file.

With SSR, the mark-up is sent to the user's DOM, which will have a link tag to your styles, the user will need to fetch, and parse styles before they render, which is what causes that flash you're talking about.

Use Styled-JSX to avoid this.

Styled-JSX will add the CSS render on the server with the rest of the content, and when served load with everything else instantly* Here's an example from their docs

function HelloWorld() {
  return (
    <div>
      Hello world
      <p>scoped!</p>
      <style jsx>{`
        p {
          color: blue;
        }
        div {
          background: red;
        }
        @media (max-width: 600px) {
          div {
            background: blue;
          }
        }
      `}</style>
      <style global jsx>{`
        body {
          background: black;
        }
      `}</style>
    </div>
  )
}

export default HelloWorld

Upvotes: 1

Related Questions