React loading third party script and calling a function from that script after

483 views Asked by At

Trying to load in a form from a third party service

They want us to load the script for their service then another script to populate the form with html/data

//load the marketo script if it doesn't exist already
const loadMarketoScript = (callback) => {
  const existingScript = document.getElementById('mktoForms');
  
  if (!existingScript) {
    const script = document.createElement('script');
    s.id = "mktoForms";
    s.type = "text/javascript";
    s.async = true;
    s.src = "//app-ab11.marketo.com/js/forms2/js/forms2.min.js";

    document.getElementsByTagName("head")[0].appendChild(script);
    script.onload = () => { 
      if (callback) callback();
    };
  }
  if (existingScript && callback) callback();
};

export default loadMarketoScript;
//page calling the function to load the script
  const [loaded, setLoaded] = useState(false);
  useEffect(() => {
    loadMarketoScript(() => {
      setLoaded(true);
    });
  });

  useEffect(() => {
    MktoForms2.loadForm("//748-KKO-677.mktoweb.com", "748-KKO-677", 1169);
  }, [loaded]);

However MktoForms2 shows as undefined. Unsure what to do here.

2

There are 2 answers

0
Drew Reese On

It seems the second useEffect hook doesn't wait for anything to actually be loaded prior to calling MktoForms2.loadForm(....);. The useEffect hook is guaranteed to be called on the initial render, and then again anytime a dependency updated.

The first useEffect hook is also missing its dependency array, so anytime the component renders the callback will be called and loadMarketoScript will be called. An empty dependency array should be added if you only want to attempt to load the market script when the component mounts.

// page calling the function to load the script
const [loaded, setLoaded] = useState(false);

useEffect(() => {
  loadMarketoScript(() => {
    setLoaded(true);
  });
}, []); // <-- add missing dependency array

useEffect(() => {
  if (loaded) { // <-- only load form if script is loaded
    MktoForms2.loadForm("//748-KKO-677.mktoweb.com", "748-KKO-677", 1169);
  }
}, [loaded]);

Alternatively you could call MktoForms2.loadForm(....); in the loadMarketoScript callback that is only ever called after the script is loaded.

// page calling the function to load the script
const [loaded, setLoaded] = useState(false);

useEffect(() => {
  loadMarketoScript(() => {
    setLoaded(true);
    MktoForms2.loadForm("//748-KKO-677.mktoweb.com", "748-KKO-677", 1169);
  });
}, []);
0
badgerhong On

If I'm understanding correctly, you want a lead association activity to prefill Marketo forms against known leads in your Marketo database, but also working with a 3rd party form.

Running through some quick checks. Make sure you:

  1. Have added Munchkin appropriately to pages
  2. Are seeing web activity for anonymous and known leads in Marketo accordingly
  3. Are not in a cross-domain browsing scenario;
  4. Have done an in-browser reality check to ensure Munchkin is loading without error (in Chrome, right click-> inspect -> sources, and do a refresh);
  5. Have not changed the primary key for new anonymous lead records from the default _mkto_trk parameter, a cookie that is created in the user's browser by Munchkin;
  6. And lastly have ensured users are meeting one of the required lead association activities: a visit to a Munchkin-tracked page with a mkt_tok parameter in the query string from a tracked Marketo email link, a Marketo form fill, or an association via SOAP syncLead or REST Associate Lead API calls.

Here is a link to documentation on Lead Association activities: https://developers.marketo.com/javascript-api/lead-tracking/

Basically, if the lead association activity is happening via click into a tracked link in a Marketo email, you'll want to make sure the click is also appending a mkt_tok parameter to the underlying URL linked in the email. If it isn't, then it's possible the destination URL either does not support URL parameters or the script you've mentioned is wiping out the mkt_tok before the lead association activity can happen, so it may be worth exploring whether or not it actually needs to load first (and perhaps, why?)

Any mismatch in the mkt_tok value appended to the URL and the expected _mkto_trk cookie in the user's browser, will cause Munchkin to associate the web activity with a new record in your anonymous leads database. For form prefill to work, we instead need this association to happen with an existing record in your known leads database.

There are some edge cases that can be solved with the knowledge here: https://experienceleague.adobe.com/docs/marketo/using/product-docs/email-marketing/general/functions-in-the-editor/disable-tracking-for-an-email-link.html

But if you've checked all the boxes, then you're likely left with one of the form prefill scenarios listed in this documentation, and you can start to solution: https://nation.marketo.com/t5/knowledgebase/form-pre-fill-feature-upgrade/ta-p/251652

If you're hosting a Marketo form on a 3rd party landing page, as your use case suggests, I'd recommend looking at the data transfer page solution outlined here: https://blog.teknkl.com/pre-fill-any-site-any-form/

In scenarios a lead association activity does not happen via tracked URL in a Marketo email, and you are (say) placing a Marketo form on a 3rd party landing page requiring data additionally be sent to (or is being received from) a separate platform, you may want to explore a solution involving a dual form submission: https://developers.marketo.com/blog/make-a-marketo-form-submission-in-the-background/

Marketo can be pretty stupid sometimes, and some of the functionality related to tracking web activities have changed with evolving data privacy laws, but the stupid tends to be systemic, so where one has run into issues, others almost certainly have as well, which means there is usually a lookalike use case from which to predicate a solution.