Implementing CSS injection on a Next.js page during server-side rendering - tips and tricks!

I recently started working with next js.

In my _app.tsx page, I have the following code:

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

The issue I am facing is that the styles - import '../styles/antd.css' are being loaded as an external request during production run at

/_next/static/css/fffc165f54adb267.css
. This results in a one second lag during the styles loading. Is there a better way to load styles in my base page without making external requests for styles?

Answer №1

Next.JS documentation discusses the process of importing CSS states.

During production, all CSS files are automatically merged into a single minified .css file.

When using SSR, the markup is transmitted to the user's DOM, with a link tag pointing to your styles. The user must fetch and interpret the styles before rendering, causing the flash effect you mentioned.

To prevent this issue, utilize Styled-JSX.

Styled-JSX ensures that the CSS renders on the server along with other content, resulting in instant loading. See an example in their documentation.

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

Answer №2

In my current setup with Next.js 13, I have shifted from using the pages/ directory to working exclusively within the /app directory. While server-side rendering (SSR) is functioning perfectly, there has been an issue with styling. Interestingly, removing the "use client"; line resolves all other issues except for styles. I have recently added the styles to the root layout located at: /app/(pages)/layout.tsx. The presence of (pages) in the path structure does not seem to be causing any problems, as it is simply used for organizing folders.

Solution

// snippet from 'next.config.js'
const path = require('path');

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

Previously, I had included the `styles` folder instead of correctly pointing to the `src` directory.

The key lesson learned here is that before SSR ("use client"), incorrect directory pointers were still functional.

It was quite challenging to identify this issue, as I initially thought SSR/CSR paths would not play a significant role. However, delving into the code abstraction revealed its importance.

In the long run, it is essential to read and comprehend the code of the packages utilized in a project. This practice enhances coding style and fosters efficient utilization of the packages.

  • Enhances your coding abilities by witnessing diverse problem-solving techniques worldwide
  • Facilitates more precise and efficient usage of packages

If anyone is encountering difficulties with applying styles such as .css or .scss/.sass, feel free to reach out for further assistance. Your feedback is valued. Thank you.

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

Answer №3

If you're working with the _app.jsx (or .tsx) file in the pages/ directory, and you're trying to load CSS, keep in mind that it will always be Client-Side Rendered (CSR), not Server-Side Rendered (SSR).

To enable SSR, you need to wrap your Component with a SSRProvider within the pages/ directory.

One popular library for this is from the Adobe team, which you can find here:

Incorporate it like this:

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

In my opinion, the app/ directory is quite reliable. Unless you're working on a critical project with zero downtime requirements affecting thousands of users, consider the switch carefully. Adequate testing can ensure reliability.

For example, using the useIsSSR() hook for testing/debugging purposes:

useOnServer.ts (hook)

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

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

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

This will provide appropriate console.log outputs for both server and client environments, demonstrating isomorphic code capabilities across both sides.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Issue encountered in Next.js 13 when trying to import the wagmi package using the app directory: The package path ./dist/chains is not exported within the package

Looking for help with Next.js 13 and importing hardhat. https://i.stack.imgur.com/PVq8G.png Snippet of the component code: "use client"; import { Faucet } from "./scaffold-eth"; import { hardhat } from "wagmi/dist/chains"; ...

The combination of Nest, Fastify, Fastify-next, and TypeOrm is unable to locate the next() function

In my attempt to set up Nest with Fastify and Next using the fastify-next plugin, everything went smoothly until I added TypeOrm for MongoDB integration. Upon loading the AppModule, Nest throws an error indicating that the .next() function cannot be found ...

What is the best way to navigate back to the top of the page once a link has been clicked?

One issue I'm facing is that whenever I click on a link in NextJS, it directs me to the middle of the page: <Link href={`/products/${id}`} key={id}> <a> {/* other components */} </a> </Link> I believe the problem l ...

Can state values be utilized as content for Meta tags?

I am looking for a way to display image previews and titles when sharing a page link. In order to achieve this, I am using the Nextjs Head Component. The necessary details are fetched on page load and used as content for the meta attributes. let campaign = ...

Minor Chrome compatibility problems with CSS alignment

As someone who is new to stackoverflow, I've always found it to be a valuable resource for answers. I've had success building HTML 5 banner ads using GSAP (Greensock Animation Platform) in the past, but now I'm facing a CSS alignment issue t ...

Arranging div elements in a vertical stack with CSS

Looking for help in arranging div elements in a way that they resemble an equalizer, similar to the one shown in this screenshot Equalizer. Can you provide advice on how to remove the dots from the list? I've already attempted using the CSS property ( ...

Ensuring the Safety of Access Tokens Automatically Generated for Firebase Storage Uploads on the Client Side

When uploading a file to Firebase Storage using the uploadBytes function from the Firebase client SDK, it automatically generates a download token and includes it in the response. Even though strict rules are set to prevent public read access, the presence ...

Leveraging VueJS 2.0 server-side rendering: Maximizing data retrieval efficiency with preFetch and beforeRouteEnter techniques

Exploring VueJS server-side rendering and troubleshooting some issues. Using the latest VueJS Hackernews 2.0 as a starting point for this project. Currently facing an obstacle: The server fetches data using the preFetch method. All seems well. When a use ...

The navigation bar extends beyond the page's width

Currently, I am working on a website that was started by a former colleague. One issue I have noticed is that when the browser window's resolution reaches 768px or lower, the navigation transforms into a drop-down menu that appears wider than the page ...

The left side of my image doesn't quite reach the edges of the screen as desired

Even after setting the padding and margin in the parent container to 0, the image is still not filling to the edges. Here is the image. This snippet of code shows my JavaScript file: import styles from './css/Home.module.css'; export default fun ...

Animate an image to the right when clicked, then return it to the left with a second click

Seeking help with animating a set of images to move individually 300px right on first click, and then 300px left when clicked again. I'm currently facing an issue where my code is not working. It could be due to A) syntax errors or B) the images not ...

Tips for accessing the @keyframes selector and extracting the value from it

In my CSS code, I have a shape element with an animation that spins infinitely for 50 seconds. #shape { -webkit-animation: spin 50s infinite linear; } @-webkit-keyframes spin { 0% { transform: rotateY(0); } 100% { transform: rotateY(-360deg ...

Automatically conceal a div or flash message after a short period of time by utilizing CSS3 in a React

I am relatively new to the React environment and recently created a basic component for a bookmarking feature. Essentially, when the favourite icon is clicked, an ajax call is sent > a record is created in the database > on ajax success, a flash me ...

NextJs/Express Server Encounters Domain HTTPS Request Error

Yesterday, I successfully deployed my website on a VPS. Everything was working fine on the VPS IP until I installed certbot on my domain. Unfortunately, I encountered the following error: Mixed Content: The page at 'https://mydomain.com/' was loa ...

The Ruby on Rails application is having trouble detecting the stylesheet in the assets

I'm having some trouble displaying a border on my buttons. The button styles are defined in the app/assets/stylesheets/modules/_buttons.scss file, which I have imported into application.scss. @import "bootstrap-sprockets"; @import "bootstrap"; //m ...

What is the best way to implement a modal that can toggle dark mode using the Konami code, with the added functionality of a close button?

Recently, I attempted to create a Modal window that would activate when the Konami code (↑↑↓↓←→←→BA) is typed. As someone new to JavaScript, I'm still learning and open to feedback. While I have the coding part figured out, I need assi ...

Learn how to dynamically add a class to an element when hovering, and ensure that the class remains even after the mouse has

I'm facing difficulty with this task - when hovering over elements, an active class should be added to them. However, when moving the mouse to another section, the active class should remain on the last element hovered. Additionally, the first block s ...

Setting the title of a NextJS site using the pages directory

Setting a title for my NextJS site has been a challenge. According to the documentation, the recommended approach is to export the metadata const with the necessary title: import { Metadata } from 'next'; export const metadata: Metadata = { ...

The CSS div mysteriously vanishes right before I can trigger the click event

My CSS code looks like this: #searchbar-wrapper input#header-searchbar:focus + #search-dropdown-wrapper { display: block; } The purpose of this code is to make a dropdown visible when a user focuses on a textbox. The default behavior should be th ...

A step-by-step guide on customizing the background color of the selected date in the MUI DatePicker

I am looking to customize the background color of selected dates in a MUI datePicker. In the image below, you can see that I want to change the blue color to a different color. Here is my code: const customStyles = makeStyles(theme => ({ datePickerC ...