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

Can markers be positioned on top of scroll bars?

Looking for a way to display small markers on the scrollbar of an overflow: scroll element, similar to features found in IDEs and text editors like this one: https://github.com/surdu/scroll-marker. I've considered using a pointer-events: none overlay ...

What is the method for determining the numerical worth of the px containers?

https://i.stack.imgur.com/0K2TD.png Total width of the bar is set to 500px, with the red box at a width of 150px, the yellow box at 200px, and the green box at 50px. CSS Styles: .box { float:left; width:150px; box-shadow:3px 3p ...

Styled-components is not recognizing the prop `isActive` on a DOM element in React

In my code, I have an svg component that accepts props like so: import React from 'react'; export default (props) => ( <svg {...props}> <path d="M11.5 16.45l6.364-6.364" fillRule="evenodd" /> </svg> ) ...

Incorporate text into the URL of the image

Got a URL of an image like this: https://lipsum.mobi/catalog/product/SE0229E/YG/AAA/4/1/SE0229E-YG-AAA-4.jpg', and looking to add 240x240 within the URL. Current Url: https://lipsum.mobi/catalog/product/SE0229E/YG/AAA/4/1/SE0229E-YG-AAA-4.jpg Desire ...

Clicking on components that are stacked on top of each

I am facing an issue with two React arrow function components stacked on top of each other using absolute positioning. Both components have onClick attributes, but I want only the one on top to be clickable. Is there a workaround for this? Here is a simpl ...

Alternate Row Colors Using Odd/Even CSS Styling for Main Headings

In my expand/collapse table, I have set up alternating row colors (dark grey and light grey) that adjust automatically when expanding or collapsing. The challenge I'm facing is that for certain rows, I want to apply a specific background color using ...

In JavaScript, the function yields a proxy rather than an object

Let's say I have an array: const arr = ['one', 'two', 'three'] Now, imagine I have a function that is designed to take an array of strings and return an array of objects: const func = (arr) => arr.map(item => ({str ...

Delivery Guy: Error: JSON parsing issue on line 1 – Unexpected number detected

I am currently learning web development and experimenting with Postman to send a POST request to one of my application's APIs. The website I am building is based on the Next.JS framework. Below is the code for my API: import type { NextApiRequest, Ne ...

Develop a CSS layout for the specified design

Aiming to achieve a unique layout using dynamic html strings. The challenge arises when transitioning to the second page as the layout does not adjust upward and images cannot be added to the first page. Attempting to implement the following sample code ...

Transitioning to EM-Based Media Queries

After the recent resolution of the WebKit page-zoom bug, what are the primary benefits of utilizing em-based media queries over pixel-based ones? Incentive I am offering a reward for my question as many prominent CSS frameworks and web developers use em- ...

Textfield style in Struts2 customization

How can I change the appearance of the textfield? [https://i.sstatic.net/TkQ0i.png] I am trying to remove the background color The code snippet in question: <s:form action ="Update_datos_XML"> <s:hidden id="id" name="id_sesion" value=" ...

Arranging List Items within a Container

What's the best way to align three different elements within a div? The elements are structured in an unordered list: Left, Center, and Right. I attempted to float the right element using float: right, and applied margin: 0 auto with a set width for ...

Flexbox: The final element is not positioned on the right side

I have been trying to align the final item on the right side using margin-left: auto. The desired output is achieved in jsfiddle. I am using Visual Studio Code with the same code, but when viewed in Firefox, Chrome, or Edge, the item does not appear on the ...

Unable to choose fields and options within the popup box

Interacting with jQuery: $("#type_name").click(function(){ $("body").append('<div class="modalOverlay">'); $("#add_form").fadeIn(1000); $("#first_name").val(""); $("#email").val(""); ...

Hover or click on HTML input type using CSS in your webpage

I am currently working on adding hover effects to my elements. I have successfully added a hover effect to the outer list item, but I am wondering how I can achieve the same effect on the <input> element instead of the <li>. ul.slides li:hov ...

The script tag in Next.js is not functioning properly, as it is throwing a ReferenceError stating that "

I have attempted numerous times using different methods but the error remains consistent. I would appreciate some guidance on this issue. import Head from 'next/head' import Script from 'next/script' export default function Home() { ...

Dynamic collapsible containers

I discovered a useful feature on w3schools for collapsing elements: https://www.w3schools.com/howto/tryit.asp?filename=tryhow_js_collapsible_symbol However, I would like to reverse it so that all elements are initially shown when the page loads, and then ...

Connecting CSS Style Sheet to JSP Page

I'm facing an issue with linking a CSS file located in my WEB-INF folder to a JSP page. In the JSP page, I have specified the location of the CSS file as follows: <link type="text/css" rel="stylesheet" href="${pageContext.request.contextPath}/WEB- ...

What is the best way to eliminate a CSS style from a div?

I have implemented jQuery Autosize to automatically adjust the height of textarea elements. It works perfectly when I focus on the textarea element. However, when I blur out of the textarea, I want to reset the height to its default value. I am unsure of ...

Angular's table data display feature is unfortunately lacking

Below is a simple HTML code snippet: <div class="dialogs"> <div id="wrapper" > <p>{{createTestingConstant()}}</p> <ng-container *ngFor="let one of contacts"> <p>{{one ...