Next.js 12.1.6引入Bootstrap CDN JS加载但不执行问题
问题场景
在Next.js 12.1.6版本中集成Bootstrap 5.1.3时,Bootstrap CSS样式可正常加载生效,但JS交互完全失效,点击导航栏折叠按钮无法展开/收起菜单。
原有问题代码
pages/_app.js 配置
import '../styles/globals.css' import Head from 'next/head'; function MyApp({ Component, pageProps }) { return ( <> <Head> <meta charset="UTF-8"/> <meta name="keywords" content="Ogani, unica, creative, html"/> <meta name="viewport" content="width=device-width, initial-scale=1"></meta> <meta http-equiv="X-UA-Compatible" content="ie=edge"/> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet"/> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script> </Head> <Component {...pageProps} /> </> ); } export default MyApp
导航栏组件代码
<nav class="navbar navbar-expand-lg navbar-light bg-light"> <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarTogglerDemo03" aria-controls="navbarTogglerDemo03" aria-expanded="false" aria-label="Toggle navigation"> <span class="navbar-toggler-icon"></span> </button> <a class="navbar-brand" href="#">Navbar</a> <div class="collapse navbar-collapse" id="navbarTogglerDemo03"> <ul class="navbar-nav mr-auto mt-2 mt-lg-0"> <li class="nav-item active"> <a class="nav-link" href="#">Home <span class="sr-only">(current)</span></a> </li> <li class="nav-item"> <a class="nav-link" href="#">Link</a> </li> <li class="nav-item"> <a class="nav-link disabled" href="#">Disabled</a> </li> </ul> <form class="form-inline my-2 my-lg-0"> <input class="form-control mr-sm-2" type="search" placeholder="Search" aria-label="Search"/> <button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button> </form> </div> </nav>
问题原因
- 版本API不匹配:当前引入的是Bootstrap 5.1.3版本,但导航栏代码沿用了Bootstrap 4的写法。Bootstrap 5对所有JS交互相关的
data-*属性统一新增了bs-命名前缀,旧版的data-toggle、data-target属性无法被Bootstrap 5的JS逻辑识别,因此不会给折叠按钮绑定展开/收起事件。 - 脚本加载时机错误:Next.js的
next/head组件仅适合加载元信息、样式等不需要操作DOM的资源,直接在Head内写入普通script标签时,脚本可能在页面DOM节点完成渲染前就执行初始化,无法找到目标DOM元素绑定事件,最终导致交互失效。 - 类名不兼容:导航栏中使用的
mr-auto、sr-only、form-inline等类名是Bootstrap 4的旧命名,在Bootstrap 5中已被替换,会导致样式错位。
修复方案
- 替换Bootstrap脚本引入方式:使用Next.js官方提供的
next/script组件加载Bootstrap JS,设置strategy="beforeInteractive"保证脚本在页面可交互前完成加载和初始化,不要把script标签放在Head组件内。 - 修正所有交互属性:将Bootstrap 4风格的
data-toggle、data-target替换为Bootstrap 5要求的data-bs-toggle、data-bs-target。 - 同步替换不兼容的类名:
mr-auto、mr-sm-2替换为me-auto、me-sm-2(Bootstrap 5改用逻辑方向命名,margin-right对应margin-end)sr-only替换为visually-hidden(屏幕阅读器专属类更名)form-inline替换为d-flex(内联表单改用flex布局实现)
修复后代码
pages/_app.js 配置
import '../styles/globals.css' import Head from 'next/head'; import Script from 'next/script'; function MyApp({ Component, pageProps }) { return ( <> <Head> <meta charSet="UTF-8"/> <meta name="keywords" content="Ogani, unica, creative, html"/> <meta name="viewport" content="width=device-width, initial-scale=1"/> <meta httpEquiv="X-UA-Compatible" content="ie=edge"/> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet"/> </Head> <Script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js" strategy="beforeInteractive" /> <Component {...pageProps} /> </> ); } export default MyApp
导航栏组件代码
<nav class="navbar navbar-expand-lg navbar-light bg-light"> <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarTogglerDemo03" aria-controls="navbarTogglerDemo03" aria-expanded="false" aria-label="Toggle navigation"> <span class="navbar-toggler-icon"></span> </button> <a class="navbar-brand" href="#">Navbar</a> <div class="collapse navbar-collapse" id="navbarTogglerDemo03"> <ul class="navbar-nav me-auto mt-2 mt-lg-0"> <li class="nav-item active"> <a class="nav-link" href="#">Home <span class="visually-hidden">(current)</span></a> </li> <li class="nav-item"> <a class="nav-link" href="#">Link</a> </li> <li class="nav-item"> <a class="nav-link disabled" href="#">Disabled</a> </li> </ul> <form class="d-flex my-2 my-lg-0"> <input class="form-control me-sm-2" type="search" placeholder="Search" aria-label="Search"/> <button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button> </form> </div> </nav>
内容的提问来源于stack exchange,提问作者Sami Ullah
相关产品推荐
相关产品推荐

