'nextjs and bootstrap5 modal

Hello I would like to use bootstrap 5 without react-bootstrap and reactstrap when I create my modal I end up with this error:

TypeError: undefined is not an object (evaluating 'this._element.classList')

Do you have any idea because all the examples I am viewing are still with reactstrap or react-bootstrap, do you have any idea how to do this, thanks for your help.

import Document, { Html, Head, Main, NextScript } from "next/document";

class MyDocument extends Document {
  static async getInitialProps(ctx) {
    const initialProps = await Document.getInitialProps(ctx);
    return { ...initialProps };
  }

  render() {
    return (
      <Html>
        <Head />
        <body>
          <Main />
          <NextScript />
          <div id="modal-root"></div>
        </body>
      </Html>
    );
  }
}

export default MyDocument;

My modal

import { useState, useEffect } from "react";
import ReactDom from "react-dom";

const Modal = ({ show, onClose, children, title, targetModal }) => {
  const [isBrowser, setIsBrowser] = useState(false);
  useEffect(() => setIsBrowser(true));

  const handleCloseModal = (e) => {
    e.preventDefault();
    let myModalEl = document.getElementById(targetModal);

    console.log(myModalEl);
    onClose();
  };

  const modalContent = show ? (
    <div
      className="modal fade py-3"
      tabIndex="-1"
      role="dialog"
      id={targetModal}
    >
      <div className="modal-dialog" role="document">
        <div className="modal-content border-0 rounded-6 shadow-blue-sm">
          <div className="modal-header p-4 pb-4 border-bottom-0">
            <h4 className="fw-bold mb-0 hstack text-secondary">
              {title && (
                <span>
                  <i className="ri-user-search-line me-2"></i> {title}
                </span>
              )}
            </h4>
            <button
              type="button"
              className="btn-close"
              data-bs-dismiss="modal"
              onClick={handleCloseModal}
              aria-label="Close"
            ></button>
          </div>

          <div className="modal-body p-4 pt-0">{children}</div>
        </div>
      </div>
    </div>
  ) : null;

  if (isBrowser) {
    return ReactDom.createPortal(
      modalContent,
      document.getElementById("modal-root")
    );
  } else {
    return null;
  }
};

export default Modal;

My Page

import { useState } from "react";

import Layouts from "@/components/Layouts";
import Modal from "@/components/Modal";

const EditEventsPage = () => {
  const [showModal, setShowModal] = useState(false);

  return (
    <Layouts title="Edit event.">
      <button
        type="submit"
        className="btn btn-secondary mt-4 hstack"
        data-bs-toggle="modal"
        data-bs-target="#uploadImage"
        onClick={() => setShowModal(true)}
      >
        <i className="ri-image-line "></i> Ajouter image{" "}
      </button>
      <Modal
        show={showModal}
        onClose={() => setShowModal(false)}
        targetModal="uploadImage"
      ></Modal>
    </Layouts>
  );
};

export default EditEventsPage;

Thansk for your helps.



Solution 1:[1]

I have not been able to achieve this using your method.

However, this works for me, and you could expand on the example.

in your _app.js file add this line of code, you should wrap it in the useEffect function as so

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

This will make bootstrap available across your project. So where ever you want to trigger your modal.

just do this instead

<button type="button" data-bs-toggle="modal" data-bs-target="#myModal">Launch modal</button>

Your Bootstrap modal

<div
      className="modal modal-alert bg-secondary py-5"
      tabIndex="-1"
      role="dialog"
      id="myModal"
    >
      <div className="modal-dialog modal-dialog-centered" role="document">
        <div className="modal-content rounded-4 shadow">
          <div className="modal-body p-4 text-center">
            <h5 className="mb-0">Enable this setting?</h5>
            <p className="mb-0">
              You can always change your mind in your account settings.
            </p>
          </div>
          <div className="modal-footer flex-nowrap p-0">
            <button
              type="button"
              className="btn btn-lg btn-link fs-6 text-decoration-none col-6 m-0 rounded-0 border-right"
            >
              <strong>Yes, enable</strong>
            </button>
            <button
              type="button"
              className="btn btn-lg btn-link fs-6 text-decoration-none col-6 m-0 rounded-0"
              data-bs-dismiss="modal"
            >
              No thanks
            </button>
          </div>
        </div>
      </div>
    </div>

Hope this helps.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Freesoul