简体   繁体   English

NextJS - 在页面组件加载时加载外部脚本

[英]NextJS - Load external script on page component load

I've migrated an old website to Nextjs and i need the scripts to load every time a page component is loaded.我已经将一个旧网站迁移到 Nextjs,每次加载页面组件时我都需要加载脚本。 But if i use the next/link component to navigate between pages, the scripts run only the first time the page is loaded.但是,如果我使用 next/link 组件在页面之间导航,则脚本仅在第一次加载页面时运行。 I've tried putting the inside the Head component in every page, but it still doesn't work.我已经尝试在每个页面中放入 Head 组件,但它仍然不起作用。 There is a workaround for this?有解决方法吗?

The two solutions to loading external scripts in Next.js seem to be to:在 Next.js 中加载外部脚本的两种解决方案似乎是:

  1. Load them using a combination of _document.js and next.config.js使用 _document.js 和 next.config.js 的组合加载它们

_document.js

          <script
            type="text/javascript"
            dangerouslySetInnerHTML={{ __html: process.env.jquery }}
          ></script>

next.config.js

const fs = require("fs")

module.exports = ({
  env: {
    jquery: fs.readFileSync("./public/js/jquery.js").toString(),
  }
})

Reference: https://stackoverflow.com/a/65349130/2167762参考: https://stackoverflow.com/a/65349130/2167762

  1. Load them using React's useEffect hook, like with a custom useScript hook /pages/index.js使用 React 的 useEffect 钩子加载它们,就像使用自定义 useScript 钩子/pages/index.js
import { useEffect } from "react"

const useScript = (url) => {
  useEffect(() => {
    const script = document.createElement("script")

    script.src = url
    script.async = true

    document.body.appendChild(script)

    return () => {
      document.body.removeChild(script)
    }
  }, [url])
}

//export default function Home({ posts }) {
export default function Home() {
  useScript("js/jquery.js")
  return <p>Component</p>
}

Reference: https://stackoverflow.com/a/34425083/2167762参考: https://stackoverflow.com/a/34425083/2167762

So which should you use?那么你应该使用哪个?

The first seems to work "great" but is actually quite buggy -- I only get the JavaScript working sometimes after refreshing in development, and never in production.第一个似乎“很好”,但实际上有很多错误——我只是让 JavaScript 在开发中刷新后才能工作,而从来没有在生产中工作。

(This would correspond to your problem with the scripts not loading when navigating with <Link> .) (这与您在使用<Link>导航时未加载脚本的问题相对应。)

The latter seems to work much better, although sometimes when I refresh in dev the scripts seem to load out of order, potentially causing runtime errors.后者似乎工作得更好,尽管有时当我在 dev 中刷新时,脚本似乎无序加载,可能导致运行时错误。

In production, however, the scripts seem to load & run consistently.然而,在生产中,脚本似乎加载和运行一致。 I haven't explicitly tested <Link> , but it should work with the useEffect() method.我没有明确测试<Link> ,但它应该与useEffect()方法一起使用。

It'll be helpful to see the scripts you're loading.查看您正在加载的脚本会很有帮助。 I faced a similar issue whiles using styled components in the version 9 of Nextjs.在 Nextjs 版本 9 中使用样式化组件时,我遇到了类似的问题。 It had something to do with the server side rendering.它与服务器端渲染有关。 Usually, using the Head should work.通常,使用Head应该可以工作。 ie. IE。

import Head from "next/head";

const HeadComponent = () => {
  return (
    <>
      <Head>
        <script src="https://code.jquery.com/jquery-3.6.0.js"></script>
      </Head>
    </>
  );
};

You could also choose to dynamically import the scripts to the root of your app using:您还可以选择使用以下方法将脚本动态导入应用程序的根目录:

import dynamic from "next/dynamic";

function MyApp({ Component, pageProps }) {
    const Script = dynamic(() => import("../Script"));
    return (
        <>
            <Component {...pageProps} />
            <Script />
        </>
    );
}

export default MyApp;

I realised that the above makes all resources load in Nextjs我意识到以上内容使所有资源都加载到 Nextjs 中

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM