Adding a custom class to the body element for specific routes in Next.js can be achieved by utilizing the features of

I am looking to apply my custom class to certain pages, with the exception of specific routes. For example, all pages should have the class fixed-header, except for the following routes:

/cart/step-1

/login

This class should be added or removed from the body element.

<body className="bg-gray fixed-header"

However, I am unsure how to implement this scenario. Any suggestions?

Answer №1

Start by creating your own custom _document.js and _app.js files within the pages directory.

Here's a handy utility function to check for classes on the body element (to prevent duplicate classes, inspired by @juliomalves):

// ./utils/hasClasses
const hasClasses = () =>
  document.body.classList.contains("bg-gray") &&
  document.body.classList.contains("fixed-header");
export default hasClasses;

Implementing Server-Side Rendering

In the _document.js file, utilize the __NEXT_DATA__ prop to access the current page, verify if the page is in your approved routes, and add appropriate classes to the body element.

import Document, { Html, Head, Main, NextScript } from "next/document";

class MyDocument extends Document {

  // Add more routes here if you wish to apply the same classes  
  allowedRoutes = ["/login", "/cart/step-1"];

  getColor() {
    const { page } = this.props?.__NEXT_DATA__;
    if (this.allowedRoutes.includes(page))
      return "bg-gray fixed-header";
    return "";
  }

  render() {
    return (
      <Html>
        <Head />
        <body className={this.getColor()}>
          <Main />
          <NextScript />
        </body>
      </Html>
    );
  }
}

export default MyDocument;

This code will execute exclusively on the server side. The classes won't be added to the body during client-side navigation.

Client-Side Rendering Solution

To address the aforementioned issue, apply the same logic found in _app.js within a useEffect hook, ensuring that the appropriate class is added during client-side rendering.

import { useEffect } from "react";
import { useRouter } from "next/router";
import "../styles.css";
import hasClasses from "./utils/hasClasses";

function MyApp({ Component, pageProps }) {

  const { pathname: page } = useRouter();
  const allowedRoutes = ["/login", "/cart/step-1"];

  useEffect(() => {
    if (!hasClasses() && allowedRoutes.includes(page))
      document.body.className += "bg-gray fixed-header";
    else if (hasClasses()) {
      // Eliminate styles on other pages to prevent conflicts.
      // Determine how to handle this based on your needs.
      document.body.classList.remove("bg-gray");
      document.body.classList.remove("fixed-header");
    }
  });
  return <Component {...pageProps} />;
}

export default MyApp;

This approach ensures proper application of classes during client-side navigation on permitted routes. The code within _document.js guarantees that pages rendered on the server are transmitted with correct styling to prevent any visual glitches on the client side.

Answer №2

If you're looking for a simple and efficient solution, this one's for you. Just insert the following code snippet into every component where you need to apply unique classes to the <body> element.

useEffect( () => { document.querySelector("body").classList.add("bg-gray fixed-header") } );

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

Accessing an array outside of an Ajax call that was initiated within a success callback

I have a CSV parsing function written in JavaScript that extracts movie names from a CSV file using an Ajax call within a loop. movies = new Array(); for (var i = 1; i < allData.length; i++) { var mName = allData[i][0]; var mPath = allData[i ...

Flot seems to be having difficulty uploading JSON files

I am relatively new to working with json and flot, but have been tasked with creating a chart. Can someone please help me troubleshoot why my code is not functioning as expected? $.getJSON('chart.json', function(graphData){ alert(graphData); ...

show image with the help of jquery and ajax

To showcase company information along with an image, I have a controller set up as follows: public JsonResult DisplayCompanyDetails() { CompanyModel cm = new CompanyModel(); string query = "select CompanyName,Address,Conta ...

Altering CSS styles through JavaScript or jQuery

Exploring Options After investigating the use of .css() to manipulate CSS properties of specific elements, I came across a website showcasing the following CSS: body, table td, select { font-family: Arial Unicode MS, Arial, sans-serif; font-size: ...

The distinction between storing data and component data becomes apparent when using Vuex in conjunction with a persisted state

Below is my post.js file in the store directory: import axios from 'axios' import createPersistedState from "vuex-persistedstate" export default { namespaced: true, state: { sample_data: 'Welcome!!', l ...

Interpret a JavaScript array response

Currently, I am working on an API request where I receive an HTTP response that contains an array with a single JSON object. However, when attempting to parse or stringify it using the following code: var response = http.response; try{ var json = J ...

What steps should be taken to fix the sinopia installation error?

While operating on redhat5.9, I encountered an exception related to 'make'. I am curious about what they are trying to create. It seems like it's related to JavaScript. [root@xxxx bin]# npm install -g sinopia --python=/usr/local/clo/ven/pyt ...

Error: Unable to load the parser '@typescript-eslint/parser' as specified in the configuration file '.eslintrc.json' for eslint-config-next/core-web-vitals

When starting a new Next.js application with the specific configuration below: ✔ What name do you want to give your project? … app ✔ Do you want to use TypeScript? … No / [Yes] ✔ Do you want to use ESLint? … No / [Yes] ✔ Do you want to use T ...

How to modify a specific property of an array object in JavaScript

I have an array of objects that looks like this: [ { number: 1, name: "A" }, { number: 2, name: "e", }, { number: 3, name: "EE", } ] I am looking for a way to insert an object into the array at a specific position and ...

Initiate a jQuery modal dialogue box

As an apprentice with no prior experience working with JavaScript, I encountered a problem with my function that calls a popup. The function works fine on the first button, but fails to work on all subsequent buttons. Since the application keeps adding b ...

What purpose does the class serve in typescript?

This is a unique version of app.component.ts in the Angular Tour of Hero tutorial. import { Component } from '@angular/core'; export class Superhero{ name : string; id : number; } const SUPERHEROES : Superhero[] = [ {name : 'Wonder ...

Error message: "SyntaxError: Unexpected token import was not caught by the foundation"

I have recently taken over development from a previous developer who integrated Zurb Foundation as a framework into our website. The Foundation framework was installed using npm. I am encountering errors in the console related to all of the foundation java ...

An issue occurred during the hydration process, causing the entire root to switch to client rendering since the error occurred outside of a Suspense boundary

I've started seeing some errors and warnings: Error: An error occurred while hydrating. Since it happened outside of a Suspense boundary, the entire root will switch to client rendering. Error: Hydration failed due to initial UI not matching what was ...

Prevent a specific folder from being included in expressjs routing

When using my expressjs app, I load public assets like this: app.use(express.static(__dirname + '/public')); Afterwards, I redirect all requests to the index, where every path is handled by Backbone app.get('*', routes.index); I am ...

React error: Objects cannot be used as children in React components

Upon trying to display data using REACT, an error message stating "Objects are not valid as a React child. If you meant to render a collection of children, use an array instead" is encountered. The issue arises when fetching records from a MongoDB collect ...

Creating a web form with HTML and integrating it with jQuery AJAX

Looking to fetch data from the server through jQuery AJAX on an HTML form and store the response in a PHP string variable. Here is my current code snippet: <form method="post" name="myform" id="myform" action="https://domain.com/cgi-bin/cgi.exe"> &l ...

Is it possible to change the button class within a div while ensuring only the last one retains the change?

Here is a code snippet I'm using to switch between classes for buttons: $('button').on('click', function(){ var btn=$(this); if(btn.attr('class')=='tct-button'){ btn.removeClass('tct-button ...

Switch the URL to the default page in next.js

I've been searching for a solution on how to change the default page path (when accessing the server via the "/" path) with no luck. I have a directory structure in place under pages as index/index.jsx, and ideally, I'd like this page to be the d ...

Prop in a React component is undergoing mutation

I encountered a strange situation where a prop in a React component is being changed. Although it's technically not a mutation since it's an array in JavaScript, it should not be modified. To replicate the issue, I created a simple example: htt ...

What is the best way to consistently and frequently invoke a REST API in Angular 8 using RxJS?

I have developed a REST API that retrieves a list of values. My goal is to immediately invoke this API to fetch values and store them in a component's member variable. Subsequently, I plan to refresh the data every five minutes. Upon conducting some ...