Next.Js Implement External ".Js" With <Script>

how do you add external javascript in Next.js?

it totally depends on how you plan to import your JS file.

Your current approach

your current approach is creating a side effect only module which your import statement initializes- that is why you see the console.log statement. to make this work just attach hello function to the window object which is not recommended.

Recommended approach

Usually, it's best to create modules without side effects. in that case to make this work you should export your function and import it in whatever module that you need.
here's an example:

console.log("script loaded!")
export function hello(){
console.log("hello!")
}

and in your module

import {hello} from 'wherever';

export default function Home() {
return (
/* some div */
{hello()}
/* the rest of the code */
)

Adding external js script to next js

in your _document.js, add script below <NextScript /> tag

<body>
<Main />
<NextScript />
<script src="assets/js/productFactory.js"></script>
</body>

How to load an external script and access it from the main bundle in nextJS

OK, I solved this using the onLoad method available on Next/Script component. What I needed to do was to move the script inclusion to my own component and include the component there adding the onLoad props and passing a function that executed my object instance after loading it.

Here my code:

const onload = () => {
const controller = new Controller(props);
setController(controller);
};
const pay = () => controller.load(props.disabled);
const attrs = {onClick: pay};
if (!controller || props.disabled) attrs.disabled = true;
return(
<>
<section className="mercadopago-checkout-pro-component">
<div ref={refContainer} className="cho-container">
<button className="btn btn-secondary" {...attrs}>
Pay
</button>
</div>
</section>
<Script src="https://sdk.mercadopago.com/js/v2" onLoad={onload}/>
</>
);

Integrate external script to nextJS

Since Marker.io doesn't provide a dedicated Next.js plugin (yet), the recommended way to integrate it is by using the dangerouslySetInnerHTML attribute from the <Script> component.

Example:

<Script
strategy="beforeInteractive"
dangerouslySetInnerHTML={{
__html: `
window.markerConfig = {
destination: '<REPLACE_ME>',
source: 'snippet'
};

!function(e,r,a){if(!e.__Marker){e.__Marker={};var t=[],n={__cs:t};["show","hide","isVisible","capture","cancelCapture","unload","reload","isExtensionInstalled","setReporter","setCustomData","on","off"].forEach(function(e){n[e]=function(){var r=Array.prototype.slice.call(arguments);r.unshift(e),t.push(r)}}),e.Marker=n;var s=r.createElement("script");s.async=1,s.src="https://edge.marker.io/latest/shim.js";var i=r.getElementsByTagName("script")[0];i.parentNode.insertBefore(s,i)}}(window,document);
`,
}}
/>

Useful links:

  • Next.js docs: Script component
  • Similar GitHub issue (solved)

Dynamically add a variable to an external js script with NextJS

Edit:

you can use react-hotjar and simply

import { hotjar } from 'react-hotjar'; 
hotjar.initialize(hjid, hjsv);// Hotjar ID and Hotjar Snippet Version

Otherwise You have 2 options:

Option 1

first make sure your package.json start script will set enviroment variable, something like this :

  "scripts": {
...
"start": "cross-env NODE_ENV=production node server.js",
...
}

Then create 2 hotjar sripts, lets say /js/prod_hotjar.js and /js/staging_hotjar.js which have appropriate SITEID inside.

Then in your _document.js detect the current enviroment, and render the appropriate script with something like this :

import Document, { Html, Head, Main, NextScript } from 'next/document'
const prod= process.env.NODE_ENV === 'production'

class MyDocument extends Document {
static async getInitialProps(ctx) {
const initialProps = await Document.getInitialProps(ctx)
return { ...initialProps }
}

render() {
const url = prod ? "/js/prod_hotjar.js" : "/js/staging_hotjar.js"
return (
<Html>
<Head>
<script src={url} ></script>
</Head>
<body>
<Main />
<NextScript />
</body>
</Html>
)
}
}

export default MyDocument

Option 2

Use dangerouslySetInnerHTML with something like this :

import Document, { Html, Head, Main, NextScript } from 'next/document'
const dev = process.env.NODE_ENV === 'production'

class MyDocument extends Document {
static async getInitialProps(ctx) {
const initialProps = await Document.getInitialProps(ctx)
return { ...initialProps }
}

render() {
const SITEID = prod ? 1234 : 4567 // or any other logic
return (
<Html>
<Head>
<script dangerouslySetInnerHTML={{__html: `(function(h,o,t,j,a,r){
h.hj=h.hj||function(){(h.hj.q=h.hj.q||[]).push(arguments)};
h._hjSettings={hjid:${SITEID},hjsv:6};
a=o.getElementsByTagName('head')[0];
r=o.createElement('script');r.async=1;
r.src=t+h._hjSettings.hjid+j+h._hjSettings.hjsv;
a.appendChild(r);
})(window,document,'https://static.hotjar.com/c/hotjar-','.js?sv=');`}} />
</Head>
<body>
<Main />
<NextScript />
</body>
</Html>
)
}
}

export default MyDocument



Related Topics



Leave a reply



Submit