1

I am working with mercadopago library. It's necessary to load the mercadopago script file and make an instance of the MercadoPago object. The thing is, nextJS loads the main bundle before including the mercadopago file, so I got an execution error because the object is not defined.

I tried different ways, loading the script file into the Head component with a normal tag and with the Next/Script object like:

<script src="https://sdk.mercadopago.com/js/v2" strategy="beforeInteractive"/>

Does not matter what I do, next always loads the script after the main bundle file. If I set a setTimeout to wait to instance the Mercadopago object it runs, but obviously this is not a good option. Which is the correct way to solve this?

juliomalves
  • 42,130
  • 20
  • 150
  • 146
jircdeveloper
  • 424
  • 2
  • 17

3 Answers3

2

Load the script in _document.js before next.js scripts, create _document.js in pages directory to extend the html document the way you like.

import Document, { Html, Head, Main, NextScript } from "next/document";

export default class MyDocument extends Document {
  render(){
    return (
      <Html>
        <Head>      
           /*This is loads the script in head tag of your html document*/      
           <script src="https://sdk.mercadopago.com/js/v2" strategy="beforeInteractive"/>
        </Head>

        <body>
          /*your script can also go here before loading next scripts*/
          <Main />
          <NextScript />
        </body>
      </Html>
    )
  }
}
Sherif Wael
  • 435
  • 2
  • 9
2

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}/>
   </>
);
jircdeveloper
  • 424
  • 2
  • 17
1

Go to your component where you need this script.

import Script from 'next/script'

const myComponent = () => {

const [razorpayInstance, setRazorpayInstance] = useState();

const handleLoadScript= () => {
var options: any = {
  "key": "myKey"
};
res = new Razorpay(options);
setRazorpayInstance(razorpay)

}

return( <> <Script id="onload-id" src="https://mycdn.com/slugs" onLoad={handleLoadScript} /> </> )}; 
export default myComponent;
ANOOP NAYAK
  • 473
  • 5
  • 8