Steps to import an external script into a NextJS application and access it from the main bundle

I have encountered an issue while working with the mercadopago library. I need to load the mercadopago script file and create an instance of the MercadoPago object. However, nextJS loads the main bundle before including the mercadopago file, resulting in an execution error due to the undefined object.

I experimented with different methods such as loading the script file into the Head component using a normal tag and also utilizing the Next/Script object like so:

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

Despite trying various approaches, Next always ends up loading the script after the main bundle file. Implementing a setTimeout function to wait for the Mercadopago object to be instantiated does work, but it is not an ideal solution. How can I correctly resolve this issue?

Answer №1

Make sure to load the script in _document.js before any next.js scripts. To do this, create a new file named _document.js in the pages directory and customize it according to your needs.

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

export default class CustomDocument extends Document {
  render(){
    return (
      <Html>
        <Head>      
           /*Include the necessary script within the head tag of the html document*/      
           <script src="https://sdk.mercadopago.com/js/v2" strategy="beforeInteractive"/>
        </Head>

        <body>
          /*You can also add additional scripts here before loading other next.js scripts*/
          <Main />
          <NextScript />
        </body>
      </Html>
    )
  }
}

Answer №2

I was able to solve this issue by utilizing the onLoad method within the Next/Script component. To resolve the problem, I moved the script inclusion to my own component and added the onLoad props while passing a function that executed my object instance after it had finished loading.

Below is the code I used:

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}/>
   </>
);

Answer №3

Head over to the component where you require this particular script.

import Script from 'next/script'

const myComponent = () => {

const [razorpayInstance, setRazorpayInstance] = useState();

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

}

return( <> <Script id="onload-id" src="https://uniquecdn.com/slugs" onLoad={handleLoadScript} /> </> )}; 
export default myComponent;

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Creating my website with a unique inverse color scheme

I'm looking to change the color scheme of my webpage so that it is inverse (white becomes black and black becomes white) similar to the Dark Reader chrome extension: https://chrome.google.com/webstore/detail/dark-reader/eimadpbcbfnmbkopoojfekhnkhdbiee ...

Click to expand for answers to commonly asked questions

Having trouble setting up a FAQs page on my blog and can't seem to get the code right. Check out what I'm trying to do here: http://jsfiddle.net/qwL33/ Everything seems fine but when I click on the first question, both questions open up. Can som ...

What is the best method to update the input(type="date") field placeholder to read as "YYYY/MM/DD"?

I've been searching for the solution to this problem all day, but I still haven't found the exact answer. Within my Next.js application, I'm utilizing MUI (V5) TextField with type "date", however, its default placeholder is "mm/dd/yyyy". How ...

I'm having trouble getting the HTML checkbox symbol to show up correctly. My goal is to create all the elements using the DOM

I am currently building all of my elements manually through the DOM tree, and I am attempting to insert a checkbox symbol in this manner: //Add date var tdDate = document.createElement("td"); tdDate.textContent = ("" + workoutList[idx].date); ...

AJAX loading footer content before images are fully loaded

I am a beginner when it comes to ajax and I'm facing an issue where the footer loads before the images, causing the images to overlap the footer. The problem is illustrated in the image below. <!doctype html> <html lang="en"> <head ...

Error encountered when attempting to resolve Angular UI Router provider

Having difficulty with integrating a resolve into a state using Angular UI router. Strangely, it works perfectly fine in another section of my code. I've organized my code into different component areas structured like this: /app /component-dashbo ...

What location is optimal for storing ng-templates within an Angular/Django single-page application?

My project involves using Django and AngularJS to create a single-page application. I have numerous ng-templates structured like this: <script type="text/ng-template" id="item.html"> // content </script> Currently, all these templates are l ...

"Ensuring Data Accuracy: Validating WordPress Fields with JavaScript

Can anyone provide assistance with this? I've been struggling for some time now. I am in need of a JavaScript code that can compare two fields in a contact form to ensure they match. For example, Phone Number and Phone Number Again. Both fields must ...

Unlocking protection: Confirming password strength and security with password indicator and regular expressions for special characters in angular through directive

I have developed an app for password validation using an AngularJS directive. The requirements for the password include at least one special character, one capital letter, one number, and a minimum length of 8 characters. Additionally, I have included a pa ...

What is the reason behind JavaScript's `fn.length` returning the count of named parameters that `fn` function has?

Why does calling fn.length in JavaScript return the number of named arguments fn has? > function fn () { } > x.length 0 > function fn (a) { } > x.length 1 > function fn (a,b,c) { } > x.length 3 This behavior is quite peculiar. I wonde ...

What is the solution to the error message stating that <tr> cannot be a child of <div>?

displayTodos() { return this.state.todos.map(function(item, index){ return <div todo={item} key = {index}>; <tr> <td>{item.todo_description}</td> <td>{item.todo_responsible}</td> ...

Ajax requests can form a pyramid of doom when multiple asynchronous calls are structured

My JavaScript application requires making an ajax call and potentially more calls based on the previous response. Currently, I have implemented this using a somewhat cumbersome pyramid of doom: function startParentArray(id) { getIssueDetail(id).succes ...

Having trouble binding form data to a React component with the onChange() method?

I've been working on developing an email platform exclusively for myself and encountered a roadblock with this React form not updating state when data is entered. After identifying the issue, it appears that the main problem lies in the React form not ...

Is it beneficial to vary the time between function calls when utilizing setInterval in JavaScript?

My website is displaying two words one letter at a time, with a 0.1s delay between letters and a 3s pause after each full word. I attempted using setTimeout, but it's not functioning as expected. What could be the issue in my code? var app = angular. ...

Invoke a Node.js script from a Spring Boot application to pass a Java object to the script. The script will modify the object and then return it back to the originating class

class Services { Address address = new Address(....); /* Invoke NodeJs script and pass address object In the js script modify address object var address = getAddress() Modify address object Return address obj ...

The disappearing act of Redux state after being added to a nested array

When attempting to update my redux state, I am facing an issue where the state disappears. My approach involves checking for a parentId - if one exists, I insert the payload into the parent's children array. However, if no parentId is provided, I simp ...

defiant underscore refusing to function

I'm currently working on a text editor, but I'm facing an issue with the remove underline functionality that doesn't seem to be working as expected. For reference, you can check out a working code example here: jsfiddle Below is the part of ...

Open a submenu when clicking on an input field and automatically close it when the focus is lost

Is there an easier way to create a submenu that opens on input click and closes when losing focus using jQuery? Right now, I have achieved this functionality with the following code: $(document).mouseup(function (e){ var container = $(".container"); ...

Using Angular to Apply a Custom Validation Condition on a FormGroup Nested Within Another FormGroup

I am facing an issue with my form validation logic. I have a set of checkboxes that need to be validated only when a specific value is selected from a dropdown. The current validator checks the checkboxes regardless of the dropdown value. Here's the c ...

What is the method for obtaining the current date when altering the system date to a previous time?

To ensure that my datepicker always displays the current date and does not allow selection of past dates, I need to update the date if the system date is in the past. If I change the system date to a past date, I don't want the datepicker to reflect t ...