1657402200
您希望将 Bootstrap 合并到 Next.js 应用程序中的原因有很多,其中之一是 Bootstrap 预构建了大量实用程序类和组件,使生活更轻松。
但是,当将 bootstrap 集成到 Next.js 应用程序(与标准 React 应用程序相反)时,会发生某些错误,尤其是在使用 Bootstrap JavaScript 功能(如切换导航栏和模式)时。而这些问题经常是由 Next.js 的 SSR 功能引起的。
服务器端渲染 (SSR) 是 Next.js 和其他 JavaScript 库/框架的一项功能,它允许 Web 应用程序将服务器上的 HTML 文件转换为客户端完全渲染的 HTML 页面。这意味着所有活动都在服务器上执行,并且作为这些过程的结果生成的标记文件将呈现给客户端。
另一方面,Bootstrap 中包含的 JavaScript 需要浏览器的document
对象才能运行。而且,因为 Next.js 默认是 SSR,这意味着document
对象在页面完全加载之前还没有准备好,这就是为什么在 Next.js 应用程序中尝试使用 Bootstrap 的 JavaScript 功能时会收到以下错误的原因:
Next.js 引导“未定义文档”错误。
本文将解释如何修复此错误以及如何在 Next.js 应用程序中有效地使用 Bootstrap 的全部功能。
有几种方法可以将 Bootstrap 合并到 Next.js 应用程序中。但是,最常见的是安装 Bootstrap 包。在开始之前,让我们创建一个新的 Next.js 应用程序:
npx create-next-app my-app
创建项目后,我们可以通过运行以下命令轻松地将最新的稳定版 Bootstrap 添加到其中:
npm install bootstrap
Bootstrap安装完成后,我们可以将缩小后的Bootstrap CSS文件导入到Next.js入口pages/_app.js
文件中,如下图:
import "bootstrap/dist/css/bootstrap.min.css"; // Import bootstrap CSS
import "../styles/globals.css";
function MyApp({ Component, pageProps }) {
return <Component {...pageProps} />;
}
export default MyApp;
与上面的代码一样,您要确保在自定义 CSS 文件之前导入了 Bootstrap,以便更容易使用此文件覆盖 Bootstrap 的默认样式(当然,如果需要的话)。
如前所述,如果我们直接导入 Bootstrap 捆绑的 JavaScript 文件,会'document is not defined'
报错。然而,我们可以利用 React 的useEffect()
Hook 来完成导入:
// src/_app.js
import { useEffect } from "react";
useEffect(() => {
require("bootstrap/dist/js/bootstrap.bundle.min.js");
}, []);
React 中的useEffect()
Hook 用于指示我们的 React 组件在渲染后需要执行某些操作,在这种情况下,我们将使用它来导入捆绑的 Bootstrap JavaScript 文件。
添加后,我们文件的完整代码_app.js
如下所示:
import "bootstrap/dist/css/bootstrap.min.css";
import "../styles/globals.css";
import { useEffect } from "react";
function MyApp({ Component, pageProps }) {
useEffect(() => {
require("bootstrap/dist/js/bootstrap.bundle.min.js");
}, []);
return <Component {...pageProps} />;
}
export default MyApp;
让我们创建一个简单的模态来尝试一下。打开默认pages/index.js
文件并将其内容替换为以下代码:
export default function Home() {
return (
<div className="d-flex
justify-content-center align-items-center">
<button
type="button"
className="btn btn-primary"
data-bs-toggle="modal"
data-bs-target="#exampleModal"
>
Launch demo modal
</button>
<div
className="modal fade"
id="exampleModal"
tabIndex="-1"
aria-labelledby="exampleModalLabel"
aria-hidden="true"
>
<div className="modal-dialog">
<div className="modal-content">
<div className="modal-header">
<h5 className="modal-title" id="exampleModalLabel">
Modal title
</h5>
<button
type="button"
className="btn-close"
data-bs-dismiss="modal"
aria-label="Close"
></button>
</div>
<div className="modal-body">...</div>
</div>
</div>
</div>
</div>
);
}
如果我们使用 ( npm run dev
) 运行我们的应用程序并在浏览器中预览它的输出,我们应该观察到一切都按预期工作:
在某些情况下,您希望以编程方式触发 Bootstrap 组件,而不是data
像我们在前面的示例中那样通过将属性添加到按钮。
例如,对于 modals,Bootstrap 包导出一个允许我们执行此操作的模块:
import bootstrap from "bootstrap";
const showModal = () => {
const myModals = new bootstrap.Modal("#exampleModal");
myModal.show();
};
但是,如果我们运行此代码,我们仍然会收到'document is not defined'
错误消息,因为我们显然也将 Bootstrap 导入了当前页面。
解决此问题的一种方法是简单地使用 JavaScript 解构语法在我们的自定义函数中导入上述模块,如下面的代码所示:
const showModal = () => {
const { Modal } = require("bootstrap");
const myModal = new Modal("#exampleModal");
myModal.show();
};
然后我们可以调用该showModal()
函数来轻松地显示我们的模态:
<button type="button" className="btn btn-primary" onClick={showModal}>
Launch demo modal
</button>
将其应用于示例页面,我们的完整代码将如下所示:
// pages/index.js
export default function Home() {
const showModal = () => {
const { Modal } = require("bootstrap");
const myModal = new Modal("#exampleModal");
myModal.show();
};
return (
<div className="d-flex">
<button type="button" className="btn" onClick={showModal}>
Launch demo modal
</button>
<div
className="modal fade"
id="exampleModal"
tabIndex="-1"
aria-labelledby="exampleModalLabel"
aria-hidden="true"
>
<div className="modal-dialog">
<div className="modal-content">
<div className="modal-header">
<h5 className="modal-title" id="exampleModalLabel">
Modal title
</h5>
<button
type="button"
className="btn-close"
data-bs-dismiss="modal"
aria-label="Close"
></button>
</div>
<div className="modal-body">
. . .
</div>
</div>
</div>
</div>
</div>
);
}
该解决方案适用于所有支持通过 JavaScript 切换的 Bootstrap 组件。以下是如何在轮播中使用它的示例:
// pages/index.js
export default function Home() {
const toggleCarousel = (action) => {
const { Carousel } = require("bootstrap");
const carousel = new Carousel("#myCarousel");
if (action === "next") {
carousel.next();
} else {
carousel.prev();
}
};
return (
<>
{" "}
<div>
<button
className="btn btn-primary"
onClick={() => toggleCarousel("prev")}
>
Prev
</button>
<button
className="btn btn-primary ms-3"
onClick={() => toggleCarousel("next")}
>
Next
</button>
</div>
<div>
<div
id="myCarousel"
className="carousel slide"
data-bs-touch="false"
data-bs-interval="false"
style={{ maxWidth: "50%", height: "80vh", overflow: "hidden" }}
>
<div className="carousel-inner">
<div className="carousel-item active">
<img src="https://picsum.photos/id/237/700/700" />
</div>
<div className="carousel-item">
<img src="https://picsum.photos/id/123/700/700" />
</div>
<div className="carousel-item">
<img src="https://picsum.photos/id/234/700/700" />
</div>
</div>
</div>
</div>
</>
);
}
运行上面的代码,我们在浏览器中得到以下输出:
您也可以将这些 Bootstrap 组件创建为自定义 React 组件,然后使用 Next.js 的动态导入功能将它们导入您的页面,同时禁用 SSR。
借助 Next.js 动态导入功能,我们可以动态导入组件并使用它们。虽然动态导入允许服务器端渲染,但我们可以根据需要禁用它。
以下是如何以这种方式导入示例组件:
import dynamic from 'next/dynamic'
const DynamicComponentNoSSR = dynamic(
() => import('../components/SampleComponent'),
{ ssr: false }
)
在位于 的组件文件中../components/SampleComponent
,我们可以在组件渲染之前运行任何客户端 JavaScript 相关代码。
为了尝试一下,让Toast.js
我们在 Next.js 项目的根源代码中创建一个新文件 ,并将以下内容粘贴到其中:
const bootstrap = require("bootstrap");
const Toast = () => {
const showToast = () => {
const toast = new bootstrap.Toast("#liveToast");
toast.show();
};
return (
<div>
<button type="button" onClick={showToast} className="btn">
Show Toast
</button>
<div className="toast-container position-fixed p-3 top-0">
<div
id="liveToast"
className="toast"
role="alert"
aria-live="assertive"
aria-atomic="true"
>
<div className="toast-header">
<img src="..." className="rounded" alt="..." />
<strong className="me-auto">Bootstrap</strong>
<small>2 secs ago</small>
<button
type="button"
className="btn-close"
data-bs-dismiss="toast"
aria-label="Close"
></button>
</div>
<div className="toast-body">
Hello, world! This is a toast message.
</div>
</div>
</div>
</div>
);
};
export default Toast;
上面的代码只是一个 BootstrapToast
组件的模板,我们使用自定义函数以编程方式触发它,如您所见,我们还在该组件的顶层导入了 Bootstrap 模块。
现在,让我们转到我们的public/index.js
文件并在禁用 SSR 的同时动态导入此组件:
import dynamic from "next/dynamic";
const Toast = dynamic(() => import("../Toast"), {
ssr: false,
});
export default function Home() {
return (
<>
<Toast />
</>
);
}
如果我们运行我们的代码并单击按钮,我们应该会看到一切正常,没有抛出任何错误:
在本文中,我们讨论了如何在 Next.js 应用程序中使用 Bootstrap 的全部功能。我们还分析了尝试使用 Bootstrap JavaScript 功能时最常见的问题,以及解决此错误的许多方法。我希望这能回答您有关将 Bootstrap 与 Next.js 集成的问题!
来源:https ://blog.logrocket.com/handling-bootstrap-integration-next-js/
1632537859
Not babashka. Node.js babashka!?
Ad-hoc CLJS scripting on Node.js.
Experimental. Please report issues here.
Nbb's main goal is to make it easy to get started with ad hoc CLJS scripting on Node.js.
Additional goals and features are:
Nbb requires Node.js v12 or newer.
CLJS code is evaluated through SCI, the same interpreter that powers babashka. Because SCI works with advanced compilation, the bundle size, especially when combined with other dependencies, is smaller than what you get with self-hosted CLJS. That makes startup faster. The trade-off is that execution is less performant and that only a subset of CLJS is available (e.g. no deftype, yet).
Install nbb
from NPM:
$ npm install nbb -g
Omit -g
for a local install.
Try out an expression:
$ nbb -e '(+ 1 2 3)'
6
And then install some other NPM libraries to use in the script. E.g.:
$ npm install csv-parse shelljs zx
Create a script which uses the NPM libraries:
(ns script
(:require ["csv-parse/lib/sync$default" :as csv-parse]
["fs" :as fs]
["path" :as path]
["shelljs$default" :as sh]
["term-size$default" :as term-size]
["zx$default" :as zx]
["zx$fs" :as zxfs]
[nbb.core :refer [*file*]]))
(prn (path/resolve "."))
(prn (term-size))
(println (count (str (fs/readFileSync *file*))))
(prn (sh/ls "."))
(prn (csv-parse "foo,bar"))
(prn (zxfs/existsSync *file*))
(zx/$ #js ["ls"])
Call the script:
$ nbb script.cljs
"/private/tmp/test-script"
#js {:columns 216, :rows 47}
510
#js ["node_modules" "package-lock.json" "package.json" "script.cljs"]
#js [#js ["foo" "bar"]]
true
$ ls
node_modules
package-lock.json
package.json
script.cljs
Nbb has first class support for macros: you can define them right inside your .cljs
file, like you are used to from JVM Clojure. Consider the plet
macro to make working with promises more palatable:
(defmacro plet
[bindings & body]
(let [binding-pairs (reverse (partition 2 bindings))
body (cons 'do body)]
(reduce (fn [body [sym expr]]
(let [expr (list '.resolve 'js/Promise expr)]
(list '.then expr (list 'clojure.core/fn (vector sym)
body))))
body
binding-pairs)))
Using this macro we can look async code more like sync code. Consider this puppeteer example:
(-> (.launch puppeteer)
(.then (fn [browser]
(-> (.newPage browser)
(.then (fn [page]
(-> (.goto page "https://clojure.org")
(.then #(.screenshot page #js{:path "screenshot.png"}))
(.catch #(js/console.log %))
(.then #(.close browser)))))))))
Using plet
this becomes:
(plet [browser (.launch puppeteer)
page (.newPage browser)
_ (.goto page "https://clojure.org")
_ (-> (.screenshot page #js{:path "screenshot.png"})
(.catch #(js/console.log %)))]
(.close browser))
See the puppeteer example for the full code.
Since v0.0.36, nbb includes promesa which is a library to deal with promises. The above plet
macro is similar to promesa.core/let
.
$ time nbb -e '(+ 1 2 3)'
6
nbb -e '(+ 1 2 3)' 0.17s user 0.02s system 109% cpu 0.168 total
The baseline startup time for a script is about 170ms seconds on my laptop. When invoked via npx
this adds another 300ms or so, so for faster startup, either use a globally installed nbb
or use $(npm bin)/nbb script.cljs
to bypass npx
.
Nbb does not depend on any NPM dependencies. All NPM libraries loaded by a script are resolved relative to that script. When using the Reagent module, React is resolved in the same way as any other NPM library.
To load .cljs
files from local paths or dependencies, you can use the --classpath
argument. The current dir is added to the classpath automatically. So if there is a file foo/bar.cljs
relative to your current dir, then you can load it via (:require [foo.bar :as fb])
. Note that nbb
uses the same naming conventions for namespaces and directories as other Clojure tools: foo-bar
in the namespace name becomes foo_bar
in the directory name.
To load dependencies from the Clojure ecosystem, you can use the Clojure CLI or babashka to download them and produce a classpath:
$ classpath="$(clojure -A:nbb -Spath -Sdeps '{:aliases {:nbb {:replace-deps {com.github.seancorfield/honeysql {:git/tag "v2.0.0-rc5" :git/sha "01c3a55"}}}}}')"
and then feed it to the --classpath
argument:
$ nbb --classpath "$classpath" -e "(require '[honey.sql :as sql]) (sql/format {:select :foo :from :bar :where [:= :baz 2]})"
["SELECT foo FROM bar WHERE baz = ?" 2]
Currently nbb
only reads from directories, not jar files, so you are encouraged to use git libs. Support for .jar
files will be added later.
The name of the file that is currently being executed is available via nbb.core/*file*
or on the metadata of vars:
(ns foo
(:require [nbb.core :refer [*file*]]))
(prn *file*) ;; "/private/tmp/foo.cljs"
(defn f [])
(prn (:file (meta #'f))) ;; "/private/tmp/foo.cljs"
Nbb includes reagent.core
which will be lazily loaded when required. You can use this together with ink to create a TUI application:
$ npm install ink
ink-demo.cljs
:
(ns ink-demo
(:require ["ink" :refer [render Text]]
[reagent.core :as r]))
(defonce state (r/atom 0))
(doseq [n (range 1 11)]
(js/setTimeout #(swap! state inc) (* n 500)))
(defn hello []
[:> Text {:color "green"} "Hello, world! " @state])
(render (r/as-element [hello]))
Working with callbacks and promises can become tedious. Since nbb v0.0.36 the promesa.core
namespace is included with the let
and do!
macros. An example:
(ns prom
(:require [promesa.core :as p]))
(defn sleep [ms]
(js/Promise.
(fn [resolve _]
(js/setTimeout resolve ms))))
(defn do-stuff
[]
(p/do!
(println "Doing stuff which takes a while")
(sleep 1000)
1))
(p/let [a (do-stuff)
b (inc a)
c (do-stuff)
d (+ b c)]
(prn d))
$ nbb prom.cljs
Doing stuff which takes a while
Doing stuff which takes a while
3
Also see API docs.
Since nbb v0.0.75 applied-science/js-interop is available:
(ns example
(:require [applied-science.js-interop :as j]))
(def o (j/lit {:a 1 :b 2 :c {:d 1}}))
(prn (j/select-keys o [:a :b])) ;; #js {:a 1, :b 2}
(prn (j/get-in o [:c :d])) ;; 1
Most of this library is supported in nbb, except the following:
:syms
.-x
notation. In nbb, you must use keywords.See the example of what is currently supported.
See the examples directory for small examples.
Also check out these projects built with nbb:
See API documentation.
See this gist on how to convert an nbb script or project to shadow-cljs.
Prequisites:
To build:
bb release
Run bb tasks
for more project-related tasks.
Download Details:
Author: borkdude
Download Link: Download The Source Code
Official Website: https://github.com/borkdude/nbb
License: EPL-1.0
#node #javascript
1625674200
In this video, we are going to implement Google Analytics to our Next JS application. Tracking page views of an application is very important.
Google analytics will allow us to track analytics information.
Frontend: https://github.com/amitavroy/video-reviews
API: https://github.com/amitavdevzone/video-review-api
App link: https://video-reviews.vercel.app
You can find me on:
Twitter: https://twitter.com/amitavroy7
Discord: https://discord.gg/Em4nuvQk
#next js #js #react js #react #next #google analytics
1625751960
In this video, I wanted to touch upon the functionality of adding Chapters inside a Course. The idea was to not think much and start the development and pick up things as they come.
There are places where I get stuck and trying to find answers to it up doing what every developer does - Google and get help. I hope this will help you understand the flow and also how developers debug while doing development.
App url: https://video-reviews.vercel.app
Github code links below:
Next JS App: https://github.com/amitavroy/video-reviews
Laravel API: https://github.com/amitavdevzone/video-review-api
You can find me on:
Twitter: https://twitter.com/amitavroy7
Discord: https://discord.gg/Em4nuvQk
#next js #api #react next js #next #frontend #development
1625699940
React development is fun because you can do a lot with Component composition. You can architect small components which are reusable and by that, you can make better sense in large projects. Small components help you manage code better. With smaller components, it’s easy to debug and refactor code. Also, over time development is very fast because most of the time you will be creating pages using the already developed set of components.
In this video, we are going to divide the Dropdown component into smaller components. We will also see how we can make the Dropdown completely dynamic in nature so that we can just pass an array and get a different dropdown.
Frontend: https://github.com/amitavroy/video-reviews
API: https://github.com/amitavdevzone/video-review-api
App link: https://video-reviews.vercel.app
You can find me on:
Twitter: https://twitter.com/amitavroy7
Discord: https://discord.gg/Em4nuvQk
#bootstrap 5 #laravel #next js #next #react #dynamic dropdown
1657402200
您希望将 Bootstrap 合并到 Next.js 应用程序中的原因有很多,其中之一是 Bootstrap 预构建了大量实用程序类和组件,使生活更轻松。
但是,当将 bootstrap 集成到 Next.js 应用程序(与标准 React 应用程序相反)时,会发生某些错误,尤其是在使用 Bootstrap JavaScript 功能(如切换导航栏和模式)时。而这些问题经常是由 Next.js 的 SSR 功能引起的。
服务器端渲染 (SSR) 是 Next.js 和其他 JavaScript 库/框架的一项功能,它允许 Web 应用程序将服务器上的 HTML 文件转换为客户端完全渲染的 HTML 页面。这意味着所有活动都在服务器上执行,并且作为这些过程的结果生成的标记文件将呈现给客户端。
另一方面,Bootstrap 中包含的 JavaScript 需要浏览器的document
对象才能运行。而且,因为 Next.js 默认是 SSR,这意味着document
对象在页面完全加载之前还没有准备好,这就是为什么在 Next.js 应用程序中尝试使用 Bootstrap 的 JavaScript 功能时会收到以下错误的原因:
Next.js 引导“未定义文档”错误。
本文将解释如何修复此错误以及如何在 Next.js 应用程序中有效地使用 Bootstrap 的全部功能。
有几种方法可以将 Bootstrap 合并到 Next.js 应用程序中。但是,最常见的是安装 Bootstrap 包。在开始之前,让我们创建一个新的 Next.js 应用程序:
npx create-next-app my-app
创建项目后,我们可以通过运行以下命令轻松地将最新的稳定版 Bootstrap 添加到其中:
npm install bootstrap
Bootstrap安装完成后,我们可以将缩小后的Bootstrap CSS文件导入到Next.js入口pages/_app.js
文件中,如下图:
import "bootstrap/dist/css/bootstrap.min.css"; // Import bootstrap CSS
import "../styles/globals.css";
function MyApp({ Component, pageProps }) {
return <Component {...pageProps} />;
}
export default MyApp;
与上面的代码一样,您要确保在自定义 CSS 文件之前导入了 Bootstrap,以便更容易使用此文件覆盖 Bootstrap 的默认样式(当然,如果需要的话)。
如前所述,如果我们直接导入 Bootstrap 捆绑的 JavaScript 文件,会'document is not defined'
报错。然而,我们可以利用 React 的useEffect()
Hook 来完成导入:
// src/_app.js
import { useEffect } from "react";
useEffect(() => {
require("bootstrap/dist/js/bootstrap.bundle.min.js");
}, []);
React 中的useEffect()
Hook 用于指示我们的 React 组件在渲染后需要执行某些操作,在这种情况下,我们将使用它来导入捆绑的 Bootstrap JavaScript 文件。
添加后,我们文件的完整代码_app.js
如下所示:
import "bootstrap/dist/css/bootstrap.min.css";
import "../styles/globals.css";
import { useEffect } from "react";
function MyApp({ Component, pageProps }) {
useEffect(() => {
require("bootstrap/dist/js/bootstrap.bundle.min.js");
}, []);
return <Component {...pageProps} />;
}
export default MyApp;
让我们创建一个简单的模态来尝试一下。打开默认pages/index.js
文件并将其内容替换为以下代码:
export default function Home() {
return (
<div className="d-flex
justify-content-center align-items-center">
<button
type="button"
className="btn btn-primary"
data-bs-toggle="modal"
data-bs-target="#exampleModal"
>
Launch demo modal
</button>
<div
className="modal fade"
id="exampleModal"
tabIndex="-1"
aria-labelledby="exampleModalLabel"
aria-hidden="true"
>
<div className="modal-dialog">
<div className="modal-content">
<div className="modal-header">
<h5 className="modal-title" id="exampleModalLabel">
Modal title
</h5>
<button
type="button"
className="btn-close"
data-bs-dismiss="modal"
aria-label="Close"
></button>
</div>
<div className="modal-body">...</div>
</div>
</div>
</div>
</div>
);
}
如果我们使用 ( npm run dev
) 运行我们的应用程序并在浏览器中预览它的输出,我们应该观察到一切都按预期工作:
在某些情况下,您希望以编程方式触发 Bootstrap 组件,而不是data
像我们在前面的示例中那样通过将属性添加到按钮。
例如,对于 modals,Bootstrap 包导出一个允许我们执行此操作的模块:
import bootstrap from "bootstrap";
const showModal = () => {
const myModals = new bootstrap.Modal("#exampleModal");
myModal.show();
};
但是,如果我们运行此代码,我们仍然会收到'document is not defined'
错误消息,因为我们显然也将 Bootstrap 导入了当前页面。
解决此问题的一种方法是简单地使用 JavaScript 解构语法在我们的自定义函数中导入上述模块,如下面的代码所示:
const showModal = () => {
const { Modal } = require("bootstrap");
const myModal = new Modal("#exampleModal");
myModal.show();
};
然后我们可以调用该showModal()
函数来轻松地显示我们的模态:
<button type="button" className="btn btn-primary" onClick={showModal}>
Launch demo modal
</button>
将其应用于示例页面,我们的完整代码将如下所示:
// pages/index.js
export default function Home() {
const showModal = () => {
const { Modal } = require("bootstrap");
const myModal = new Modal("#exampleModal");
myModal.show();
};
return (
<div className="d-flex">
<button type="button" className="btn" onClick={showModal}>
Launch demo modal
</button>
<div
className="modal fade"
id="exampleModal"
tabIndex="-1"
aria-labelledby="exampleModalLabel"
aria-hidden="true"
>
<div className="modal-dialog">
<div className="modal-content">
<div className="modal-header">
<h5 className="modal-title" id="exampleModalLabel">
Modal title
</h5>
<button
type="button"
className="btn-close"
data-bs-dismiss="modal"
aria-label="Close"
></button>
</div>
<div className="modal-body">
. . .
</div>
</div>
</div>
</div>
</div>
);
}
该解决方案适用于所有支持通过 JavaScript 切换的 Bootstrap 组件。以下是如何在轮播中使用它的示例:
// pages/index.js
export default function Home() {
const toggleCarousel = (action) => {
const { Carousel } = require("bootstrap");
const carousel = new Carousel("#myCarousel");
if (action === "next") {
carousel.next();
} else {
carousel.prev();
}
};
return (
<>
{" "}
<div>
<button
className="btn btn-primary"
onClick={() => toggleCarousel("prev")}
>
Prev
</button>
<button
className="btn btn-primary ms-3"
onClick={() => toggleCarousel("next")}
>
Next
</button>
</div>
<div>
<div
id="myCarousel"
className="carousel slide"
data-bs-touch="false"
data-bs-interval="false"
style={{ maxWidth: "50%", height: "80vh", overflow: "hidden" }}
>
<div className="carousel-inner">
<div className="carousel-item active">
<img src="https://picsum.photos/id/237/700/700" />
</div>
<div className="carousel-item">
<img src="https://picsum.photos/id/123/700/700" />
</div>
<div className="carousel-item">
<img src="https://picsum.photos/id/234/700/700" />
</div>
</div>
</div>
</div>
</>
);
}
运行上面的代码,我们在浏览器中得到以下输出:
您也可以将这些 Bootstrap 组件创建为自定义 React 组件,然后使用 Next.js 的动态导入功能将它们导入您的页面,同时禁用 SSR。
借助 Next.js 动态导入功能,我们可以动态导入组件并使用它们。虽然动态导入允许服务器端渲染,但我们可以根据需要禁用它。
以下是如何以这种方式导入示例组件:
import dynamic from 'next/dynamic'
const DynamicComponentNoSSR = dynamic(
() => import('../components/SampleComponent'),
{ ssr: false }
)
在位于 的组件文件中../components/SampleComponent
,我们可以在组件渲染之前运行任何客户端 JavaScript 相关代码。
为了尝试一下,让Toast.js
我们在 Next.js 项目的根源代码中创建一个新文件 ,并将以下内容粘贴到其中:
const bootstrap = require("bootstrap");
const Toast = () => {
const showToast = () => {
const toast = new bootstrap.Toast("#liveToast");
toast.show();
};
return (
<div>
<button type="button" onClick={showToast} className="btn">
Show Toast
</button>
<div className="toast-container position-fixed p-3 top-0">
<div
id="liveToast"
className="toast"
role="alert"
aria-live="assertive"
aria-atomic="true"
>
<div className="toast-header">
<img src="..." className="rounded" alt="..." />
<strong className="me-auto">Bootstrap</strong>
<small>2 secs ago</small>
<button
type="button"
className="btn-close"
data-bs-dismiss="toast"
aria-label="Close"
></button>
</div>
<div className="toast-body">
Hello, world! This is a toast message.
</div>
</div>
</div>
</div>
);
};
export default Toast;
上面的代码只是一个 BootstrapToast
组件的模板,我们使用自定义函数以编程方式触发它,如您所见,我们还在该组件的顶层导入了 Bootstrap 模块。
现在,让我们转到我们的public/index.js
文件并在禁用 SSR 的同时动态导入此组件:
import dynamic from "next/dynamic";
const Toast = dynamic(() => import("../Toast"), {
ssr: false,
});
export default function Home() {
return (
<>
<Toast />
</>
);
}
如果我们运行我们的代码并单击按钮,我们应该会看到一切正常,没有抛出任何错误:
在本文中,我们讨论了如何在 Next.js 应用程序中使用 Bootstrap 的全部功能。我们还分析了尝试使用 Bootstrap JavaScript 功能时最常见的问题,以及解决此错误的许多方法。我希望这能回答您有关将 Bootstrap 与 Next.js 集成的问题!
来源:https ://blog.logrocket.com/handling-bootstrap-integration-next-js/