What is the best way to integrate Bootstrap 5 with Next.js?

After adding Bootstrap to my project with npm install bootstrap, I included the style in /pages/_app.js like this:

import 'bootstrap/dist/css/bootstrap.css';
export default function App({ Component, pageProps }) {
    return <Component {...pageProps} />
}

However, any JavaScript functionality, such as the Collapse example from the Bootstrap docs, does not work at all.

function App() {
    return (
      <div>
        <p>
          <a class="btn btn-primary" data-bs-toggle="collapse" href="#collapseExample" role="button" aria-expanded="false" aria-controls="collapseExample">
            Link with href
          </a>
          <button class="btn btn-primary" type="button" data-bs-toggle="collapse" data-bs-target="#collapseExample" aria-expanded="false" aria-controls="collapseExample">
            Button with data-bs-target
          </button>
        </p>
        <div class="collapse" id="collapseExample">
          <div class="card card-body">
            Some placeholder content for the collapse component. This panel is hidden by default but revealed when the user activates the relevant trigger.
          </div>
        </div>
      </div>
    );
}
export default App

If I include

import 'bootstrap/dist/js/bootstrap.js'
in /pages/_app.js, it starts working as expected. However, upon page reload, I encounter a
ReferenceError: document is not defined
error (screenshot). This makes me question whether using Bootstrap with React or Next.js is feasible or advisable.
I assumed that with jQuery being dropped, Bootstrap 5 should be compatible out of the box with frameworks like React (eliminating the need for react-bootstrap or reactstrap).

Is there a proper way to implement Bootstrap 5 with Next.js? Or should I consider alternative solutions or revert to using reactstrap (which currently only supports Bootstrap 4)?

Answer №1

When transitioning to NextJS, there is a common oversight that many of us tend to make.

Issue: ReferenceError: Document is not defined.

Cause: NextJS executes the application on the server side where there is no global window or document object available. This results in the document variable being undefined. You can easily test this by printing out the types of window and document using

console.log(typeof window, typeof document)
.

https://i.stack.imgur.com/yFraH.png

So, what's the solution?

I found a workaround by adding the following code snippet to my function component:

    useEffect(() => {
        typeof document !== undefined ? require('bootstrap/dist/js/bootstrap') : null
    }, [])

The use of useEffect with an empty dependency array mimics the behavior of componentDidMount(), ensuring that the code runs after the initial server-side rendering and then client-side execution. This prevents any errors from occurring as the client has access to the document object.

I have completely moved away from using `componentDidMount()` nowadays.

Was this approach successful for me?

To validate this, I replicated your Collapse example in another application.

https://i.stack.imgur.com/Cu077.png

Answer №2

Instructions:

  1. First, use npm to install bootstrap.
  2. Next, include the bootstrap library in the _app.js file.
import Head from 'next/head';
import Script from 'next/script';
import React, { useEffect } from 'react';
import '../styles/global.scss';
import 'bootstrap/dist/css/bootstrap.css';

export default function App({ Component, pageProps }) {
  useEffect(() => {
    import("bootstrap/dist/js/bootstrap");
  }, []);

  useEffect(() => {
    import("jquery/dist/jquery.min.js");
  }, []);

  useEffect(() => {
    typeof document !== undefined ? require('bootstrap/dist/js/bootstrap') : null;
  }, []);

  return (
    <>
      <Head>
        <meta name='viewport' content='width=device-width, initial-scale=1' />
      </Head>
      <Component {...pageProps} />
    </>
  );
}

Answer №3

It seems that React Bootstrap has now incorporated support for Bootstrap5 as of July 2021: Check out the image from their website below:

https://i.stack.imgur.com/ceRR7.png

Answer №4

There is a distinction between the _app.js and _app.tsx files

function MyApp({ Component, pageProps }: AppProps) {
  // load bootstrap-js-libs below for _app.js
  useEffect(() => {
     import("bootstrap/dist/js/bootstrap");
   }, []);

  useEffect(() => {
    typeof document !== undefined ? require("bootstrap/dist/js/bootstrap") : null;
  }, []);

We can also utilize CDN in the _document file!

Answer №5

Indeed, using a CDN link for Bootstrap is a simple way to integrate it into your project.

Syntax:

export default function Document() {
  return (
    <Html>
      <Head>
        
<!-- Include Bootstrap via CDN -->
<link
          href="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="bcded3d3c8cfc8ceddccfc89928c928c91ded9c8dd8d">[email protected]</a>/dist/css/bootstrap.min.css"
          rel="stylesheet"
          integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1"
          crossOrigin="anonymous"
        />




      </Head>
      <body>
        <Main />
        <NextScript />
      </body>
    </Html>
  );
}

Check out the project I'm currently developing:

https://i.stack.imgur.com/ySBqO.png

Here's the output of the project (Bootstrap button):

https://i.stack.imgur.com/E4TYS.png

Answer №6

When importing bootstrap.css, don't forget to also import the bootstrap.js file in order to use collapse functionality. Bootstrap's js requires jquery and popper, although react or nextjs advise against using jquery.

Instead, consider using one of the following alternative libraries:

  1. react-bootstrap
  2. reactstrap

For the latest version of bootstrap 5, you can utilize BootstrapCDN:

In _document.js, add the following 2 lines:

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="ceaca1a1babdbabcafbe8efbe0fee0ff">[email protected]</a>/dist/css/bootstrap.min.css" integrity="undefined" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="16747979626562647766562338263827">[email protected]</a>/dist/js/bootstrap.min.js" integrity="undefined" crossorigin="anonymous"></script>

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

How to properly align TableHeader and TableBody contents in a Material-UI table

I am experiencing an issue with a file that is supposed to display a table of data pulled from a database. Although the table does appear, all the data seems to be displayed under the ISSUE NUMBER column, instead of being aligned with their respective col ...

Challenges with dynamically adding rows using jQuery

I am trying to create a dynamic form that allows users to select a project and then populates tasks based on the selected project from a database query. The user can then enter hours for each task, which are updated based on the project id and task id comb ...

Sending JSON Data from C# to External JavaScript File without Using a Web Server

Trying to transfer JSON data from a C# (winforms) application to a static HTML/JavaScript file for canvas drawing without the need for a web server. Keeping the HTML file unhosted is preferred. Without involving a server, passing data through 'get&ap ...

LESS — transforming data URIs with a painting mixin

Trying to create a custom mixin for underlining text, similar to a polyfill for CSS3 text-decoration properties (line, style, color) that are not yet supported by browsers. The idea is to draw the proper line on a canvas, convert it to a data-uri, and the ...

What is the reason for having both the Video.js npm module and the <script> tag in place?

After referring to the official Video.js documentation at , it is recommended to add script tags for both js and css to your webpage. Additionally, you can install the package manager through npm or bower. What is the purpose of utilizing both approaches? ...

Is there a way to efficiently display more than 10 data items at a time using the FlatList component in react-native?

Here is the data I am working with: singlePost?.Comments = [ 0: {id: 82, content: "Parent1", responseTo: null} 1: {id: 83, content: "Child1", responseTo: 82} 2: {id: 84, content: "Parent2", response ...

execute a post request with dynamic data to API using nextjs httpService

I am trying to make a call to an endpoint located at using nestjs. However, I keep encountering the following error message: data 13 - XML tags should be given in the POST variable "data" const { data } = await firstValueFrom( this.httpService .post ...

Building mobile apps with React Native involves passing functions through props

Recently diving into the world of react native, I find myself facing a challenge with passing a function from a parent class to a child class. //Child class const AppDrawer = ({update_recent}) => { update_recent("Notification"); } //Pare ...

What steps can I take to get Node.js up and running smoothly once more?

Lately, I have been using npm to work on a project with angular. However, 3 days ago, after my Windows system updated, npm stopped working completely. When I tried to run npm install The terminal displayed the following error: npm ERR cb() never called! ...

React not showing multiple polylines on the screen

I'm currently working on an application aimed at practicing drawing Kanji characters. To draw the lines, I'm utilizing svg. The issue I've encountered is that when I try to draw multiple separate lines using a 2D array of points for each lin ...

The call to the hook is invalid. In order to use hooks, they must be called within the body of a function component in

So, in my upcoming application, I am incorporating the react-google-one-tap-login library which features the useGoogleOneTapLogin hooks that need to be invoked within a React component. However, when I attempt to use it in this manner: func() { useGoogle ...

Unveiling the Power of KnockoutJS: Displaying HTML Content and Populating

I am trying to achieve a unique effect using KnockoutJS. Let's consider a basic model: var Item = function () { var self = this; self.title = ko.observable(""); }; In addition, I have a ViewModel: var ItemList = function () { var self = ...

The text displayed using react-pdf appears in various locations on the page

In my project, I am working on incorporating react-pdf to display Hebrew PDF files. I am looking to make specific words clickable with links to other pages, like Wikipedia. To achieve this, I am experimenting with a customTextRenderer function, focusing on ...

Export Webdatarock as HTML directly in React without triggering a download

Is it possible to retrieve the webdatarock table in HTML format without having to download it in React JS? I have found success using the following code in JavaScript: pivot.exportTo("html", { destinationType: "server", url: "&quo ...

Is Angular Translate susceptible to race conditions when using static files for multi-language support?

Currently utilizing angular translate with the static files loader for implementing multiple languages in my project. However, I've encountered a problem where the loading of language files sometimes takes longer than loading the actual view itself, l ...

Retrieve all records that contain a specific field using Mongoose

I am trying to retrieve documents from my schema that have a string field called companyName. The object I receive from the query string looks like this: {companyName:"Amazon,Microsoft"}}. How can I find and return all documents that have a compa ...

Clicking on the anchor at the bottom of the page will smoothly navigate you to the top of the page

I added an anchor at the bottom of the page. I wrapped a group of buttons with the link so that when clicked, they trigger the assigned JavaScript and scroll to the bottom of the page. However, the buttons currently execute the JavaScript but then take you ...

Mongoose encountered a TypeError due to the undefined value of t.versions.node

Seeking assistance! I have a Next.js application that was working perfectly fine. However, after making a few updates on the GitHub code and deploying it through DeployBot, I encountered the following error: Being new to this, I am not sure what steps to t ...

Allowing users to easily copy and paste within expansion panels

Currently, I am exploring the possibilities of utilizing the ExpansionPanel component provided by Material-UI. However, I am encountering a challenge in enabling text selection on the ExpansionPanelSummary component to allow users to Copy and Paste text ...

Can HTML/CSS be used to specifically target handheld mobile devices?

I am looking to optimize my video display in HTML by only showing it on desktop browsers. The difference in bandwidth between desktop and mobile devices is affecting the performance of mobile browsers, so I want to target only desktop users. Is there a way ...