Next.js 13 App目录下Bootstrap导航栏折叠功能失效求助
Next.js 13 中 Bootstrap 导航栏折叠功能失效的解决方法
问题描述
在Next.js 13中无法正常使用Bootstrap导航栏的折叠功能,已尝试两种方法:
- 在head标签中添加Bootstrap JS脚本
- 在Layout页面中引入相关代码
均未解决问题。该功能此前在CRA和react-bootstrap中可正常运行。
提供的代码
Header组件
"use client"; import Image from "next/image"; import React, { useContext, useEffect } from "react"; import Link from "next/link"; import bootstaplogo from "../asset/b1.svg"; import { RiMailSendLine, RiLoginBoxFill, RiPencilFill, RiLogoutBoxFill, } from "react-icons/ri"; import { AuthContext } from "../context/authContext"; import Cart from "./Cart"; import { usePathname } from "next/navigation"; const Header = () => { const currentPathname = usePathname(); const { currentUser, logout } = useContext(AuthContext); useEffect(() => { // Load Bootstrap JS only on the client-side if (typeof window !== "undefined") { require('bootstrap/dist/js/bootstrap.bundle.min'); } }, []); return ( <> <div> <div className="container"> <nav className=" bg-light navbar navbar-expand-md navbar-light fixed-top border-bottom"> <div href="/" className=" navbar-brand ps-5 d-flex align-items-center mb-3 mb-md-0 me-md-auto text-dark text-decoration-none" > <Image alt="logo" className="me-2" width="40" height="32" src={bootstaplogo} ></Image> <span className="fs-4">deneme</span> </div> <button className="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNavDropdown" aria-controls="navbarNavDropdown" aria-expanded="false" aria-label="Toggle navigation" > <span className="navbar-toggler-icon" /> </button> <div className="navbar-toggle" id="navbarNavDropdown"> <div className="collapse navbar-collapse justify-content-end "> <ul className="navbar-nav"> <li className="nav-item"> <Link className= {currentPathname === "/" ? " active nav-link" : "nav-link"} href="/"> {" "} AnaSayfa </Link> </li> <button className="btn btn-warning px-3 me-2"> <RiMailSendLine /> İletişim{" "} </button> </div> </div> </nav> </div> </div> </> ); }; export default Header;
Layout组件
import './globals.css' import { Inter } from 'next/font/google' import Footer from '../component/Footer' import Header from '@/component/Header' const inter = Inter({ subsets: ['latin'] }) import 'bootstrap/dist/css/bootstrap.css' import {AuthContexProvider} from "../context/authContext" import { CartProvider } from '../context/CartContext' export const metadata = { title: 'Create Next App', description: 'Generated by create next app', } export default function RootLayout({ currentPathname, children }) { return ( <html lang="tr"> <AuthContexProvider> <CartProvider><Header currentPathname={currentPathname}/> <div className={`mt-5 ${inter.className}`} >{children} <Footer/></div> </CartProvider></AuthContexProvider> </html> ) }
解决方案
1. 修正导航栏HTML结构错误
你的导航栏结构存在核心问题:折叠按钮的data-bs-target="#navbarNavDropdown"指向的ID,错误地加在了外层的div.navbar-toggle上,而实际的折叠内容容器是内层的div.collapse navbar-collapse。
正确结构应该是:
<button className="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNavDropdown" aria-controls="navbarNavDropdown" aria-expanded="false" aria-label="Toggle navigation" > <span className="navbar-toggler-icon" /> </button> {/* 把ID直接加在折叠容器上,删除多余的外层div.navbar-toggle */} <div className="collapse navbar-collapse justify-content-end" id="navbarNavDropdown"> <ul className="navbar-nav"> <li className="nav-item"> <Link className={currentPathname === "/" ? " active nav-link" : "nav-link"} href="/"> AnaSayfa </Link> </li> <button className="btn btn-warning px-3 me-2"> <RiMailSendLine /> İletişim{" "} </button> </ul> </div>
2. 修复Layout的DOM结构缺失
你的RootLayout缺少<body>标签,Next.js 13要求Layout必须包含<html>和<body>,缺失会导致DOM结构异常,影响Bootstrap的功能。
3. 正确加载Bootstrap JS
推荐在Layout中通过next/script组件加载Bootstrap CDN脚本,确保在客户端正确执行,避免手动require的时机问题:
修改后的Layout代码:
import './globals.css' import { Inter } from 'next/font/google' import Footer from '../component/Footer' import Header from '@/component/Header' import Script from 'next/script' const inter = Inter({ subsets: ['latin'] }) import 'bootstrap/dist/css/bootstrap.css' import {AuthContexProvider} from "../context/authContext" import { CartProvider } from '../context/CartContext' export const metadata = { title: 'Create Next App', description: 'Generated by create next app', } export default function RootLayout({ currentPathname, children }) { return ( <html lang="tr"> <body> <AuthContexProvider> <CartProvider> <Header currentPathname={currentPathname}/> <div className={`mt-5 ${inter.className}`} > {children} <Footer/> </div> </CartProvider> </AuthContexProvider> {/* 加载Bootstrap JS,确保客户端交互后执行 */} <Script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js" strategy="afterInteractive" /> </body> </html> ) }
4. 移除Header中冗余的Bootstrap加载代码
删除Header组件中useEffect里的require('bootstrap/dist/js/bootstrap.bundle.min'),避免重复加载导致冲突。
内容的提问来源于stack exchange,提问作者M.Mustafa ÖZAYDIN
相关产品推荐
相关产品推荐

