Where to import bootstrap js file in next js 13 using new "app directory" – Next.js

by
Ali Hasan
bootstrap-5 next.js next.js13

The Problem:

In Next.js 13, after the introduction of the new "app directory", importing the Bootstrap JS file in the layout component is not working as expected. The UI elements work, but the JavaScript features, like dropdowns, are not functioning due to the "document not defined" error.

The Solutions:

Solution 2: Import Bootstrap dynamically

To import the Bootstrap JS only on the client side in Next.js 13, you can use the dynamic function in layout.tsx as follows:

import 'bootstrap/dist/css/bootstrap.css';
import dynamic from 'next/dynamic';

const DynamicBootstrap = dynamic(
  () => require('bootstrap/dist/js/bootstrap.min.js'),
  { ssr: false }
);

This ensures that the Bootstrap JS is only loaded on the client side, avoiding the document not defined error.

Solution 3: Using BootstrapProvider

To resolve the issue with Bootstrap JS functionalities not working in Next.js 13 with the new "app directory," you can implement this solution:

providers/bootstrap.js

"use client"
import React, { createContext, useContext, useEffect, useState } from "react";

const Context = createContext(undefined);

function Providers({ children }) {
  const [Bootstrap, setBootstrap] = useState(undefined);

  useEffect(() => {
    if (!Bootstrap) {
      const BS = require("bootstrap/dist/js/bootstrap.bundle.min.js");
      setBootstrap(BS);
    }
  }, []);

  return (
    <Context.Provider value={{ Bootstrap }}>
      {children}
    </Context.Provider>
  );
}

export const useBootstrap = () => {
  const context = useContext(Context);

  if (context === undefined) {
    throw new Error("useBootstrap must be used inside BootstrapProvider");
  }

  return context;
};

export default Providers;

layout.tsx

import "bootstrap/dist/css/bootstrap.min.css";
import "../styles/_global.scss";

import { Metadata } from "next";

import BootstrapProvider from "@/providers/bootstrap";

export const metadata: Metadata = {};

export default function RootLayout({ children }) {
  return (
    <html>
      <body>
        <BootstrapProvider>{children}</BootstrapProvider>
      </body>
    </html>
  );
}

client-side component

"use client"
import { useBootstrap } from "@/providers/bootstrap";

export default () => {
  const { Bootstrap } = useBootstrap();

  const toggle = (event) => {
    event.preventDefault();
    new Bootstrap.Collapse(`#collapse-id`).toggle();
  };

  return (
    <a href="#" onClick={toggle}>Toggle</a>
  );
};

Solution: Manually Integrate Bootstrap JS in RootLayout

You can manually integrate the Bootstrap JS in the RootLayout component. This method is explicit and gives you more control over the process. Additionally, it ensures compatibility with both client-side and server-rendered components.

Here’s how to do it:

  1. Import the Script component from next/script.
  2. Import Bootstrap’s CSS file.
  3. In the RootLayout component, add the following code to include the Popper and Bootstrap JS files:
import Script from 'next/script';
import 'bootstrap/dist/css/bootstrap.css';

export default function RootLayout({ children }) {
  return (
    <html lang="en">
      <body>
        {children}
        <Script src="https://cdn.jsdelivr.net/npm/@popperjs/[email protected]/dist/umd/popper.min.js" />
        <Script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.min.js" />
      </body>
    </html>
  );
};

This approach allows you to include Bootstrap everywhere without concerns about server-side rendering or client-side rendering.

Q&A

Where "bootstrap" js file should be imported in next js 13 using new "app directory"?

You can import it in the RootLayout component in "app/layout.tsx" file.

Why importing in layout.tsx is throwing error => "document not defined"?

Because you need to use "use client" directive and define a null component to import the bootstrap js file.

How to style the "RootLayout" component globally?

You can define global styles in the "app/globals.css" file.

Video Explanation:

The following video, titled "Install Next.js & Bootstrap Using Pages Router - YouTube", provides additional insights and in-depth exploration related to the topics discussed in this post.

Play video

Get started creating a landing page using Next.js. This video will cover several useful topics that will get you setup and ready to build a ...