Having trouble importing Bootstrap into Next.js? It seems like the issue may be related to the

I am currently facing an issue with importing bootstrap 5.3.2 (not react-bootstrap) into my NextJS 14.1.0 project that utilizes the new App Router. My goal is to strategically utilize individual Bootstrap components (not through data-attrs).

I managed to make it work but I keep encountering a persistent error 500 every time I perform a hard refresh. The console keeps showing this specific message:

 ⨯ node_modules/bootstrap/dist/js/bootstrap.esm.js (803:18) @ document
 ⨯ ReferenceError: document is not defined
    at __webpack_require__ (/Users/rsilva/Desktop/bs/.next/server/webpack-runtime.js:33:42)
    at eval (./app/TooltipComponent.js:9:67)
    at (ssr)/./app/TooltipComponent.js (/Users/rsilva/Desktop/bs/.next/server/app/page.js:162:1)
    at __webpack_require__ (/Users/rsilva/Desktop/bs/.next/server/webpack-runtime.js:33:42)

Below are the relevant snippets of code:

layout.js

import "bootstrap/dist/css/bootstrap.css";
import BootstrapProvider from "./providers/bootstrap";

export default function RootLayout({ children }) {
  return (
    <html lang="en">
      <body className="container my-5">
        <BootstrapProvider/>
        {children}
      </body>
    </html>
  );
}

My BS provider (bootstrap.js):

"use client";

import { useEffect } from 'react';

function BootstrapProvider() {
  useEffect(() => {

    async function loadBootstrap() {
      const bootstrap = await import('bootstrap/dist/js/bootstrap.bundle.min.js');
      window.bootstrap = bootstrap;
    }

    loadBootstrap();
    
  }, []);

  return null;
}

export default BootstrapProvider;

page.js

import { TooltipComponent } from "./TooltipComponent";

export default function Home() {
  return (
    <main>
      
     <TooltipComponent title="Test">
        test tooltip
      </TooltipComponent>
      
    </main>
  );
}

Lastly, here's the component where the Tooltip is used programmatically:

"use client";

import { useEffect, useRef } from "react";
import { Tooltip } from "bootstrap";

export function TooltipComponent({
  children,
  title = "Missing tooltip 'title' property",
  placement = "top",
  trigger = "hover",
}) {
  const tooltipRef = useRef();

  useEffect(() => {
    if (title) {
      const tooltip = new Tooltip(tooltipRef.current, {
        title: title,
        placement: placement,
        trigger: trigger,
        container: "body",
      });
      return () => {
        tooltip.dispose();
      };
    }
  }, [title]);

  return <span ref={tooltipRef}>{children}</span>;
}

Any suggestions or insights on how to resolve this issue would be greatly appreciated. Thank you!

Answer №2

To include the condensed Bootstrap CSS file in the entry pages/_app.js file of Next.js:

import "bootstrap/dist/css/bootstrap.min.css"; 
Also, import bootstrap CSS with "../styles/globals.css";

function MyApp({ Component, pageProps }) {   return <Component {...pageProps} />; }

export default MyApp;

Answer №3

Have you considered utilizing react-bootstrap for your project?

With react-bootstrap, you can easily integrate Bootstrap into your React application without the need to set up a Bootstrap Provider or link vanilla Bootstrap globally.

Check out this Example Tooltip to see it in action.

EDIT

Instead of importing Tooltip in your component, you could include the Bootstrap JavaScript file directly in the script tag and use it similarly to how you would in vanilla JavaScript or jQuery.

import Script from 'next/script'
 
export default function Page() {
  return (
    <>
      <Script src="bootstrap/dist/js/bootstrap.bundle.min.js" strategy="afterInteractive" />
    </>
  )
}

You can implement the tooltip functionality within a component like so:

"use client";

export function TooltipComponent({
  children,
  title = "Missing tooltip 'title' property",
  placement = "top",
  trigger = "hover",
}) {
  return <span data-bs-toggle="tooltip" data-bs-placement={placement} title={title}>{children}</span>;
}

Answer №4

When you encounter the

ReferenceError: document is not defined
issue, it's because Bootstrap JavaScript code is running in server-side rendering (SSR) where there is no DOM present. Bootstrap's JavaScript needs the DOM to function properly. This leads to Bootstrap attempting to access the document object during SSR but failing due to the absence of a DOM, resulting in the error message.

To fix this error, you must ensure that the Bootstrap JavaScript is only loaded on the client side where the DOM exists. Modifications should be made to the TooltipComponent.tsx file as shown in the comments section below.

"use client";

import { useEffect, useRef } from "react";
// Remove this
// import { Tooltip } from "bootstrap";

export function TooltipComponent({
  children,
  title = "Missing tooltip 'title' property",
  placement = "top",
  trigger = "hover",
}) {
  const tooltipRef = useRef();

  useEffect(() => {
    // Add this
    const { Tooltip } = require("bootstrap");

    if (title) {
      const tooltip = new Tooltip(tooltipRef.current, {
        title: title,
        placement: placement,
        trigger: trigger,
        container: "body",
      });
      return () => {
        tooltip.dispose();
      };
    }
  }, [title]);

  return <span ref={tooltipRef}>{children}</span>;
}

I was able to resolve the error by following these steps, as indicated in the screenshot below (taken after refreshing the page).

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

If you encounter any further issues, feel free to reach out. I created the Next.js app from scratch, so my code may differ slightly. In such cases, I will update my response with complete code examples for all relevant files (layout.tsx, page.tsx, tooltip.tsx, bootstrap.js, etc.).

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

MVC5 Toggle Button for Instant Display and Concealment

I used to utilize this method in Web Form development by targeting the id and name of the input radio button. However, I am encountering difficulties implementing it in MVC5. Can someone kindly point out where I might be going wrong? Upon selecting a radi ...

Numerous conversations happening simultaneously on one screen

I'm currently in the process of creating two Dialog modals using @material-ui/core. Here is my current file structure: |-components/ |-|-index.js |-|-common/ |-|-|-header.jsx |-|-|-searchModal.jsx |-|-|-signModal.jsx My goal is to import these two d ...

Node.js application - varying NODE_ENV upon NPM launch

Operating my node.js application can be quite confusing. When launched by npm start, it operates in "production" mode, whereas when launched using node start.js, it runs in 'development' mode. I want to ensure that the 'development' mo ...

Invoke a Python function from JavaScript

As I ask this question, I acknowledge that it may have been asked many times before. If I missed the answers due to my ignorance, I apologize. I have a hosting plan that restricts me from installing Django, which provided a convenient way to set up a REST ...

Using Selenium to interact with drop-down lists using div tags instead of select tags

As a newcomer to automated testing using Selenium Web Driver, I am struggling to test drop down lists for the location type without relying on the select command. The element in question is enclosed within a div tag. I attempted sending keys but that meth ...

Understanding 'this' in ChartJS within an Angular application

Here is my event handler for chartJS in Angular that I created: legend: { onClick: this.toggleLegendClickHandler After changing the text of the y scale title, I need to update the chart. I am looking to accomplish this by calling this._chart.cha ...

The image source failed to load the image using the function

Initially, I set up a sandbox to work on this issue: https://codesandbox.io/s/naughty-almeida-u66mlt?file=/src/App.js The main problem arises when the requested image fails to display after the function is called and the URL is returned. Here are my atte ...

Caution: Potential Unresolved Promise Rejection Detected (ID: 21) - Error: Undefined is not a valid object when trying to evaluate 'res.json'

ERROR Getting an Unhandled Promise Rejection (id: 21): TypeError: undefined is not an object (evaluating 'res.json'). Any suggestions on fixing this issue in my code? I've checked the logs for user and loggeduserobj, and they seem to be cor ...

Executing a function on the window object in JavaScript

I have come across the following code and am seeking guidance on how to get the last line to function correctly. The API I am using currently employs _view appended as its namespacing convention, but I would prefer to switch to something like arc.view.$f ...

Getting a JWT token from Express to Angular using ngResource: A step-by-step guide

Currently, I am utilizing a jwt token for user registration validation. A unique URL is generated and sent to the user via email, which leads them to the authentication page. On the server side, the token is decoded and I need to transmit this JSON data to ...

Material UI makes it possible for the ToggleButtonGroup to maintain a consistent fixed size regardless of its content

Seeking a solution to ensure consistent button sizes, even when they have no content. The desired size is displayed below, functioning properly as long as the top and bottom buttons contain some content: https://i.stack.imgur.com/5zVNM.png When the midd ...

What is the best way to generate an array from JSON data while ensuring that the values are not duplicated?

Upon receiving a JSON response from an API, the structure appears as follows: { "status": "success", "response": [ { "id": 1, "name": "SEA BUSES", "image": null }, { "id": 2, ...

The conflict arises when importing between baseUrl and node_modules

I am currently working on a TypeScript project with a specific configuration setup. The partial contents of my tsconfig.json file are as follows: { "compilerOptions": { "module": "commonjs", "baseUrl": &quo ...

Replacing variables in a function: A step-by-step guide

I have frequently used the replace function to eliminate classes in JavaScript. Currently, I am working on creating a JavaScript function that allows me to remove a specific class from an element by passing in the element and the class name. changeAddress ...

Issue encountered while utilizing JQueryUI alongside TypeScript and the definition file from DefinitelyTyped

Currently, I'm attempting to incorporate JQueryUI with TypeScript by first installing JQueryUI using npm install jquery-ui-dist, and then installing JQuery with npm install jquery. Additionally, I have included the definition files from DefinitelyType ...

Every individual child component must be assigned a distinct key prop, even if they are pre-defined. - Utilizing REACT

My navigation bar routes are sourced from a JSON file structured like this: { "categorias": [ { "nombre": "Teacher absences", "componentes": [ { "type": "url", ...

The act of employing `Function.prototype.run` within an Angular TypeScript class is deemed as illegitimate

Is there a way to globally define a new function called run within my Angular component as shown below? Function.prototype.run = function (delay: number) { // some content; }; However, the compiler shows an error that the Property 'run' does n ...

When using jQuery Ajax, only pass the query string if it is defined and not empty

Using jquery and ajax to communicate with a CMS API, I am constructing a query string to fetch data: region = typeof region !== 'undefined' ? 'region='+region : ''; centre = typeof centre !== 'undefined' ? 'cen ...

Unexpected behavior: JQuery Ajax request not displaying Json object following recent update to JQuery version 1.10.2

Currently facing an issue with a project I am working on. The previous programmer used jquery 1.4.4, and I have updated it to 1.10.2 due to the designer using Bootstrap. However, after running it in version 1.10.2, one of the objects that was functional i ...

Material UI React's FormControl

Hello there! Can you tell me what makes FormControl from Material UI unique? Does it indicate that the child element is being controlled? <FormControl> <InputLabel htmlFor="my-input">Email address</InputLabel> <Input id ...