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:
- Import the
Script
component fromnext/script
. - Import Bootstrap’s CSS file.
- 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.
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 ...
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.
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 ...