Reputation: 271
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
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
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:
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
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.
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