How to add form capture from Microsoft Dynamics in a SPA app?

Viewed 24

We are using React in a SPA. When we use a form of a page without navigation Microsoft Dynamics form capture works fine. But if we come from another page that has a form and we navigate via React-router to another page that has another form, then the form stops working. How can we solve this? I think is related to SPA applications.

This is the component that adds the script to MS Dynamics:

const SOURCE = '...SOURCE...'; // ..../public/latest/js/form-loader.js?v=1.84.2007
const WEBSITE_ID = '...WEBSITE_ID...';
const HOSTNAME = '...HOSTNAME...';

let alreadyLoaded = false;

export default function MSDynamicsForm() {
  useEffect(loadDynamics, []);
  function loadDynamics() {
    if (alreadyLoaded) return
    const script = document.createElement('script');
    script.src = SOURCE;
    script.async = true;
    document.body.insertBefore(script, document.body.childNodes[0]);
    alreadyLoaded = true;
  }

  return (
    <div
      className="d365-mkt-config"
      style={{ display: 'none' }}
      data-website-id={WEBSITE_ID}
      data-hostname={HOSTNAME}
      data-no-submit="true"
    />
  );
}

Thanks!

1 Answers

Adding this to the useEffect clear method:

  • Remove script
  • Remove injected code in window
  • Remove injected iframe from MS Dynamics

Now is working fine, loading from scratch the script navigating to another page:


export default function MSDynamicsForm() {
  useEffect(loadDynamics, []);
  function loadDynamics() {
    const script = document.createElement('script');
    script.src = SOURCE;
    script.async = true;
    document.body.insertBefore(script, document.body.childNodes[0]);

    return () => {
      document.body.removeChild(script);
      // @ts-ignore
      window.MsCrmMkt = undefined;
      const iframe = document.querySelector('iframe[src*="dynamics.com"]');
      if (iframe) iframe.remove();
    };
  }

  return (
    <div
      className="d365-mkt-config"
      style={{ display: 'none' }}
      data-website-id={WEBSITE_ID}
      data-hostname={HOSTNAME}
      data-no-submit="true"
    />
  );
}

However, it is not a very elegant solution. If anyone has a better answer, you are welcome.

Related