2

I was trying to use a template of bootstrap, CSS files are imported properly by I'm not able to import JS. I came to know that in Next Js you can import them in useEffect hook. But still, it gives an error that the script not found. Here is my code,

import Head from 'next/head';
import '../styles/globals.css';
import { useEffect } from 'react';

function MyApp({ Component, pageProps }) {
  useEffect(() => {
    import("../public/lib/js/jquery-3.3.1.min.js");
    import("../public/lib/js/bootstrap.min.js");
    import("../public/lib/js/jquery.nice-select.min.js");
    import("../public/lib/js/jquery-ui.min.js");
    import("../public/lib/js/jquery.slicknav.js");
    import("../public/lib/js/mixitup.min.js");
    import("../public/lib/js/owl.carousel.min.js");
    import("../public/lib/js/main.js");
  }, []);
  return (
      <>
      <Head>

        <meta charset="UTF-8"/>
        <meta name="keywords" content="Ogani, unica, creative, html"/>
        <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
        <meta http-equiv="X-UA-Compatible" content="ie=edge"/>

        {/* Font */}
        <link href="https://fonts.googleapis.com/css2?family=Cairo:wght@200;300;400;600;900&display=swap" rel="stylesheet"/>
        {/* CSS */}
        <link rel="stylesheet" href="lib/css/bootstrap.min.css" type="text/css"/>
        <link rel="stylesheet" href="lib/css/font-awesome.min.css" type="text/css"/>
        <link rel="stylesheet" href="lib/css/elegant-icons.css" type="text/css"/>
        <link rel="stylesheet" href="lib/css/nice-select.css" type="text/css"/>
        <link rel="stylesheet" href="lib/css/jquery-ui.min.css" type="text/css"/>
        <link rel="stylesheet" href="lib/css/owl.carousel.min.css" type="text/css"/>
        <link rel="stylesheet" href="lib/css/slicknav.min.css" type="text/css"/>
        <link rel="stylesheet" href="lib/css/style.css" type="text/css"/>


      </Head>
      <Component {...pageProps} />
      </>
   );
  }
  export default MyApp;

Here is my directory structure,

Directory Structure

After the suggestion is used _document.js inside the pages directory to include local scripts but still they aren't included when the page is rendered.

pages/_document.js code is below,

import { Html, Head, Main, NextScript } from 'next/document'
import Script from 'next/script'

export default function Document() {
  return (
    <Html>
      <Head>
            {/* Site Tag */}
            <Script src="lib/js/jquery-3.3.1.min.js" strategy="beforeInteractive"/>
            <Script src="lib/js/bootstrap.min.js" strategy="beforeInteractive"/>
            <Script src="lib/js/jquery.nice-select.min.js" strategy="beforeInteractive"/>
            <Script src="lib/js/jquery-ui.min.js" strategy="beforeInteractive"/>
            <Script src="lib/js/jquery.slicknav.js" strategy="beforeInteractive"/>
            <Script src="lib/js/mixitup.min.js" strategy="beforeInteractive"/>
            <Script src="lib/js/owl.carousel.min.js" strategy="beforeInteractive"/>
            <Script src="lib/js/main.js" strategy="beforeInteractive" />
      </Head>
      <body>
        <Main />
        <NextScript />
      </body>
    </Html>
  );
}
juliomalves
  • 42,130
  • 20
  • 150
  • 146
Sami Ullah
  • 33
  • 1
  • 7
  • Have a look at this: https://nextjs.org/docs/basic-features/script#overview and this: https://nextjs.org/docs/api-reference/next/script to see if they solve your problem. They explain the correct ways to include scripts in a NextJS project. – Chizaram Igolo Jun 13 '22 at 08:26
  • @ChizaramIgolo I've tried that already. Script tag loads from 3rd party CDN etc. I want to load the script files from my public directory. There is no example of loading from the public directory with a Script tag. – Sami Ullah Jun 13 '22 at 08:33
  • Okay, I get you. For the benefit of those who may ask the same question in the future, please see my answer. – Chizaram Igolo Jun 13 '22 at 09:25
  • 1
    @ChizaramIgolo please check the above I edited and posted as per your answer. – Sami Ullah Jun 13 '22 at 10:10
  • Using the `beforeInteractive` strategy in `_document` currently doesn't work as expected. See [Why does the next.js Script tag with the beforeInteractive strategy don't load thirdParty script?](https://stackoverflow.com/questions/72332146/why-does-the-next-js-script-tag-with-the-beforeinteractive-strategy-dont-load-t) for a solution/workaround. – juliomalves Jun 13 '22 at 10:25
  • @juliomalves I've tried adding using script tag with deferring attr. But after adding like this when I load my website it gives an error, "Error: Hydration failed because the initial UI does not match what was rendered on the server." Tags are added like this in _document.js body, – Sami Ullah Jun 13 '22 at 11:00
  • That may related to how you're using those third-party libraries in your codebase. Probably worth asking about that in a different question with more details and a proper [mre]. – juliomalves Jun 13 '22 at 11:02
  • @juliomalves what's improper the way I asked this question everything is clear and precise. "That may related to how you're using those third-party libraries in your codebase" yes I know that, but what's the solution? – Sami Ullah Jun 13 '22 at 11:22
  • @juliomalves still i posted a new question ---> https://stackoverflow.com/questions/72602177/next-js-fails-to-load-third-party-script-in-document-js – Sami Ullah Jun 13 '22 at 11:41
  • What I meant was, the new issue is most likely not related to the scripts imports, but to how you're using the code that is imported by the scripts, hence why a new question may be better suited to address that. – juliomalves Jun 13 '22 at 12:01

1 Answers1

1

Update:

Changed beforeInteractive to lazyOnload. You may also use afterInteractive.


Say you have a local script file: myscript.js that you are trying to include in your NextJS project, to include it:

  1. Place the script file in your /public folder and

  2. In your page component add:


Inside page component:

import Script from 'next/script'

export default function Document() {
  return (
    <div>
       {/* Other stuff */}
        <Script
          src="myscript.js"
          strategy="lazyOnload"
        />
    </div>
  )
} 

NextJS will know to look for scripts referenced without a URL prefix like https in the public folder.

Learn more about the <Script> component and other load strategys here:

https://nextjs.org/docs/basic-features/script#overview and https://nextjs.org/docs/api-reference/next/script

Chizaram Igolo
  • 907
  • 8
  • 18