You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js Link组件致导航栏加载异常,求正确用法与依赖引入方式

问题解决:Next.js Link组件导航失效与第三方依赖正确引入

一、修复Link组件的使用方式

你的问题核心是Link组件的包裹层级错误,导致DOM结构不符合Bootstrap、Mega Menu等第三方插件的预期,进而引发样式和交互失效。

正确写法(分Router版本)

1. Pages Router(Next.js 12及以下)

使用passHref属性让Link把href传递给内部<a>标签,同时调整层级让Link直接包裹<a>而非<li>:

import Link from 'next/link';

// 导航项渲染代码
return (
  <li className="nav-item dropdown position-static active" key={index}>
    <Link href={`/${item.id}`} passHref>
      <a className="nav-link">{item.categoryName}</a>
    </Link>
  </li>
);
  • 禁止嵌套<a>标签:原写法中Link会生成顶层<a>,内部又自定义了<a>,属于无效HTML,会导致插件无法识别交互元素。
  • passHref作用:确保内部<a>能拿到正确href属性,同时保留Link的客户端导航特性。

2. App Router(Next.js 13+)

App Router的Link组件可直接作为导航元素使用,无需嵌套<a>,直接添加className即可:

import Link from 'next/link';

// 导航项渲染代码
return (
  <li className="nav-item dropdown position-static active" key={index}>
    <Link href={`/${item.id}`} className="nav-link">
      {item.categoryName}
    </Link>
  </li>
);
  • App Router的Link会自动渲染为<a>标签,完全兼容第三方插件对<a>元素的事件监听逻辑。

二、第三方依赖的正确引入方式

你当前直接在HTML中插入script标签的方式,会导致客户端导航后新DOM无法被插件初始化(SPA跳转不刷新页面,脚本仅执行一次),同时不利于Next.js的打包优化。

方案1:npm安装+动态客户端导入(推荐)

  1. 先通过npm安装核心依赖:
npm install bootstrap jquery popper.js
  1. 在_app.js(Pages Router)或layout.js(App Router)中导入CSS,并动态导入JS(确保仅在浏览器端执行):
// Pages Router: pages/_app.js
import 'bootstrap/dist/css/bootstrap.css';
import '../styles/globals.css';
import { useEffect } from 'react';

function MyApp({ Component, pageProps }) {
  useEffect(() => {
    // 动态导入客户端脚本,避免SSR时报错
    import('jquery').then($ => {
      window.$ = $;
      // 导入Bootstrap(已包含Popper)
      import('bootstrap/dist/js/bootstrap.bundle.min.js');
      // 依次导入自定义脚本
      import('../vendor/mega-menu/assets/js/custom.js');
      import('../vendor/aos-next/dist/aos.js');
      import('../vendor/jquery.appear.js');
      import('../vendor/jquery.countTo.js');
      import('../vendor/mixitup-3/mixitup.min.js');
      import('../js/theme.js');
    });
  }, []);

  return <Component {...pageProps} />;
}

export default MyApp;

方案2:CDN引入+路由变化时重新初始化插件

如果坚持使用CDN,需要在导航数据加载完成后,手动重新初始化第三方插件:

  1. 在_document.js(Pages Router)或root layout(App Router)中添加CDN脚本:
// Pages Router: pages/_document.js
import Document, { Html, Head, Main, NextScript } from 'next/document';

class MyDocument extends Document {
  render() {
    return (
      <Html>
        <Head>
          {/* 可选:通过CDN引入样式 */}
          <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" />
        </Head>
        <body>
          <Main />
          <NextScript />
          {/* 第三方脚本放在NextScript后,确保Next.js核心脚本先加载 */}
          <script src="http://localhost:3000/vendor/jquery.min.js"></script>
          <script src="http://localhost:3000/vendor/popper.js/popper.min.js"></script>
          <script src="http://localhost:3000/vendor/bootstrap/js/bootstrap.min.js"></script>
          <script src="http://localhost:3000/vendor/mega-menu/assets/js/custom.js"></script>
          <script src="http://localhost:3000/vendor/aos-next/dist/aos.js"></script>
          <script src="http://localhost:3000/vendor/jquery.appear.js"></script>
          <script src="http://localhost:3000/vendor/jquery.countTo.js"></script>
          <script src="http://localhost:3000/vendor/mixitup-3/mixitup.min.js"></script>
          <script src="http://localhost:3000/js/theme.js"></script>
        </body>
      </Html>
    );
  }
}

export default MyDocument;
  1. 在导航组件的useEffect中,数据加载完成后重新初始化插件:
useEffect(() => {
  fetchCategory().then(res => {
    setCategory(res);
    // 等待DOM更新后执行初始化
    setTimeout(() => {
      if (window.$) {
        // 重新初始化Bootstrap下拉菜单
        window.$('.dropdown').dropdown();
        // 初始化Mega Menu(根据custom.js的实际方法调整)
        if (window.initMegaMenu) {
          window.initMegaMenu();
        }
        // 刷新AOS动画
        if (window.AOS) {
          window.AOS.refresh();
        }
      }
    }, 0);
  });
}, [router.pathname, id]);

额外注意事项

  • 确保第三方脚本依赖的全局变量(如$)仅在客户端环境中存在,避免SSR时抛出错误。
  • 客户端导航时,Next.js不会重新执行全局脚本,因此必须在路由变化或数据更新后手动初始化新增的DOM元素。

内容的提问来源于stack exchange,提问作者OchkoMN

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 14:15:13