How can I use Bootstrap 5 with Next.js?

12,905

Solution 1

This is a common thing that most of us miss while switching to NextJS.

Problem: Document is not defined.

Reason: NextJS renders your app at server, and there is no window, document etc. on server, hence document is not defined. you can even console.log(typeof window, typeof document) to verify this.

enter image description here

NOW, what is the solution?

I used this code in my function component:

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

useEffect with empty dependencies works like componentDidMount() which runs after the code is run second time. Since code runs first at server and then at client, it will not produce errors, as client has document.

I've never used `componentDidMount(), ever.

Did that worked for me?

I just copied your Collapse example in my other app to verify this.

enter image description here

Solution 2

Steps: 1- Install bootstrap through npm. 2- now add bootstrap in _app.js.

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} />
    </>
  );
}
Share:
12,905
DavidPH
Author by

DavidPH

Updated on June 07, 2022

Comments

  • DavidPH
    DavidPH almost 2 years

    After installing bootstrap with npm install bootstrap I added the style to /pages/_app.js like so:

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

    However anything from it that uses javascript does not work at all, e.g. the Collapse example from their docs.

    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 add import 'bootstrap/dist/js/bootstrap.js' to /pages/_app.js then it starts "working" as expected, until a page reload in which it says ReferenceError: document is not defined (screenshot), which leads me to believe it's not possible or that I shouldn't try to use boostrap + react or next.js.
    I had thought them dropping jquery meant that it should work just "out of the box" with frameworks like react (as in not needing react-boostrap or reactstrap anymore)

    Is there a way to properly use boostrap 5 and nextjs? Or should I just try something else entirely or go back to using reactstrap (which currently seems to only support boostrap 4)?

    • paulsm4
      paulsm4 almost 3 years
      Yes, you can definitely use Bootstrap 5 from Angular, Next and ReactJS. And no, it has nothing to do with "dropping jQuery" (although I happen to LOVE jQuery!) Look here for several solutions: stackoverflow.com/a/65260998/421195. Please post back what worked for you!
    • DavidPH
      DavidPH almost 3 years
      @paulsm4 thanks for reply, my line of thinking that it's not possible to use comes from seeing multiple posts saying it's dumb to use bootstrap and react and that you should use material ui instead. But since I know bootstrap I want to try use it if it's possible. As for the question you linked, none of that worked for me. I still get "document is not defined" or if I use the top answer I get "window is not defined"
    • Mhmdrz_A
      Mhmdrz_A over 2 years
  • DavidPH
    DavidPH almost 3 years
    Normally I'd say I appreciate any reply but it's as if you didn't read the question. 1) I'm showing how I'm attempting to import bootstrap's js and failing. 2) I'm asking about bootstrap 5, and react-bootstrap + reactstrap are for bootstrap 4, 3) I mentioned those in my post anyway, 4) bootstrap 5 is designed to be used without jquery
  • DavidPH
    DavidPH almost 3 years
    Brilliant, thank you so much. Although for mine I had to add import { useEffect } from 'react'(else useeffect was undefined) at the top which I notice you don't have , is that correct? This is my entire /pages/_app.js now pastebin.com/raw/2qbEMxXp
  • ChrisW
    ChrisW almost 3 years
    @DavidPH Excellent! Your pastebin code worked right away, except that in my default Next.js app global.css is spelled '../styles/globals.css'. - I was also required to install popper for it to work: yarn add @popperjs/core