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:
Thanks so much!
Solved! Go to Solution.
Works as on any 3rd-party site or framework. React outputs HTML + JS like anything else that's eventually viewed in a browser!
Thanks!!!
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.
How can I load this Marketo form into a Gatsby page? Any help or suggestions are greatly appreciated!
Nevermind. Figured it out
Thought you would. I didn't have time this week to mock it up in React.
Hi Noah — I am currently stuck in a similar spot. Are you willing to share the solution you came up with? Thanks!
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.
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.