SOLVED

Re: React Website + Marketo

Go to solution
Noah_Wong1
Level 2

React Website + Marketo

I am developing a microsite that will be integrated with our Marketo instance. I am interested in using React to build the site. Two questions:

  1. Will Marketo munchkin code work on a React website? Forms?
  2. If it does work fine, any watchouts or documentation on how to integrate with Marketo?

Thanks so much!

Tags (1)
1 ACCEPTED SOLUTION

Accepted Solutions
SanfordWhiteman
Level 10 - Community Moderator

Re: React Website + Marketo

Works as on any 3rd-party site or framework. React outputs HTML + JS like anything else that's eventually viewed in a browser!

View solution in original post

9 REPLIES 9
SanfordWhiteman
Level 10 - Community Moderator

Re: React Website + Marketo

Works as on any 3rd-party site or framework. React outputs HTML + JS like anything else that's eventually viewed in a browser!

Noah_Wong1
Level 2

Re: React Website + Marketo

Thanks!!!

Noah_Wong1
Level 2

Re: React Website + Marketo

Sanford Whiteman So back at this.

I am trying to add a Marketo form into a Gatsby site but have trouble with the order in which scripts are injected into the page.

When I try to render the component below, I get the error message "ReferenceError: MktoForms2 is not defined".

I tried commenting out the entire useEffect code block and the component renders to the page fine without the form. Then when I paste "MktoForms2.loadForm("//app-sj11.marketo.com", "XXX-XXX-XXX", 1608)" into the console, the form appears as expected.

import React, { useEffect } from "react";
import Helmet from "react-helmet";

import "./form.scss";

const FormContactMkto = () => {
useEffect(() => {
MktoForms2.loadForm("//app-sj11.marketo.com", "XXX-XXX-XXX", 1608);
}, []);

return (
<div>
<Helmet>
<script
src="//app-sj11.marketo.com/js/forms2/js/forms2.min.js"
type="text/javascript"
/>
</Helmet>
<form id="mktoForm_1608"></form>
</div>
);
};

export default FormContactMkto;

How can I load this Marketo form into a Gatsby page? Any help or suggestions are greatly appreciated!

Noah_Wong1
Level 2

Re: React Website + Marketo

Nevermind. Figured it out

SanfordWhiteman
Level 10 - Community Moderator

Re: React Website + Marketo

Thought you would.  I didn't have time this week to mock it up in React.

Aakash_Shah
Level 1

Re: React Website + Marketo

Hi Noah — I am currently stuck in a similar spot. Are you willing to share the solution you came up with? Thanks!

Noah_Wong1
Level 2

Re: React Website + Marketo

Sure. I'd be interested if anyone else has a thought of a better way. I ended up loading the form library during the Build sequence by adding it to the gatsby-ssr.js file

const React = require("react");

exports.onRenderBody = ({ setHeadComponents }) => {
return setHeadComponents([
<script
id="marketo-js"
key="marketo-form"
src="//app-sj11.marketo.com/js/forms2/js/forms2.min.js"
/>
]);
};

Then I stripped the the Marketo form styles by adding this excellent snippet from Sanford Whiteman during the Client sequence in the gatsby-browser.js file

require("./src/css/style.css");

exports.onInitialClientRender = () => {
function destyleMktoForm(mktoForm, moreStyles) {
var formEl = mktoForm.getFormElem()[0],
arrayFrom = Function.prototype.call.bind(Array.prototype.slice);

// remove element styles from <form> and children
var styledEls = arrayFrom(formEl.querySelectorAll("[style]")).concat(
formEl
);
styledEls.forEach(function(el) {
el.removeAttribute("style");
});

// disable remote stylesheets and local <style>s
var styleSheets = arrayFrom(document.styleSheets);
styleSheets.forEach(function(ss) {
if (
[mktoForms2BaseStyle, mktoForms2ThemeStyle].indexOf(ss.ownerNode) !=
-1 ||
formEl.contains(ss.ownerNode)
) {
ss.disabled = true;
}
});

if (!moreStyles) {
formEl.setAttribute("data-styles-ready", "true");
}
}

MktoForms2.whenRendered(function(form) {
destyleMktoForm(form);
});
};

Lastly, I built this Form Component that I send with some props.

import React, { useEffect } from "react";

const MktoForm = props => {
useEffect(() => {
MktoForms2.loadForm("//app-sj11.marketo.com", "XXX-XXX-XXX", props.formId);
}, []);

return (
<div className="bg-gray-300 shadow rounded p-3">
<div className="text-lg font-bold uppercase">{props.heading}</div>
<div className="text-sm mb-6">{props.subheading}</div>
<div
style={{
height: `${props.height}`,
overflow: "hidden"
}}
>
<form id={`mktoForm_${props.formId}`}></form>
</div>
</div>
);
};

export default MktoForm;

The only caveat in doing it this way is that the form will load more than once if you rapidly go back and forth from that page to another. The first form load doesn't complete in time before its called a second time. Gatsby is a little too fast for its own good . This is why I set a fixed height to the parent div with overflow:hidden (to hide the subsequent form loads).

This is the solution that I came up with but if anyone knows how to kill the api call to load the form when the component unmounts, I would love to hear it.

Aakash_Shah
Level 1

Re: React Website + Marketo

Thank you for the detailed explanation Noah Wong

Vipin_Mp
Level 2

Re: React Website + Marketo

Hi Noah,

 

in your comment, the form will load more than once if you rapidly go back and forth from that page to another, if the form load doesn't complete in time before it's called a second time. I have the same case, but by setting overflow: hidden to hide the repeating form, are you able to submit the form ("if the form consists of mandatory fields"), as I'm not able to submit the form as the validation error throwing from the hidden form field elements.