How to add a Marketo Form into a Gatsby Site

Portland, Oregon

As a digital marketing professional, I am by nature drawn to the latest web and marketing technologies. At the current moment, I am fully invested in Gatsby for website development and Marketo for marketing automation.

But how do you marry these two awesome technologies?

Strike Out

This was tough to figure out finally.

I wanted to embed a Marketo form into a Gatsby website but the embed code that Marketo provides does not work when directly copy and pasted into a Gatsby site. There are some modifications needed but I have been able to get it working.

I ended up loading the form library during the Build sequence by adding it to the gatsby-ssr.js file

// gatsby-ssr.js

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 applying this destyled function to the form during the Client sequence in the gatsby-browser.js file.

// gatsby-browser.js

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 styles
    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)
  })
}

I built this Form Component that uses the useEffect hook to load the Marketo form when the page mounts and include some props. One of the props is the height of the div that contains the form. If you don't set this height to the div then the form will not appear.

// MktoForm.jsx

import React, { useEffect } from "react";
import PropTypes from "prop-types";

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

  return (
    <div className="form">
      <div className="form__heading">{heading}</div>
      <div className="form__subheading">{subheading}</div>
      <div
        style={{
          height: `${height}`,
          overflow: "hidden",
        }}
      >
        <form id={`mktoForm_${formId}`}></form>
      </div>
    </div>
  );
};

MktoForm.defaultProps = {
  heading: `Form Heading`,
  height: `50px`,
  subheading: `Form Subheading`,
};

MktoForm.propTypes = {
  formId: PropTypes.string.isRequired,
  heading: PropTypes.string,
  height: PropTypes.string,
  subheading: PropTypes.string,
};

export default MktoForm;

Then I use add the Form component to the page that I want to embed the form with the necessary props.

// contact.jsx

import React from "react";
import MktoForm from "../components/Forms/MktoForm";
import Layout from "../components/layout";

const ContactPage = () => {
  return (
    <Layout>
      <div>
        <MktoForm
          heading="Get in touch with us"
          subheading="Please fill out the form and we will be in touch with lighnting speed."
          formId="1616"          height="330px"        />
      </div>
    </Layout>
  );
};

export default ContactPage;

Noah Wong

I am an always curious, strategic-creative digital creator. I have a real passion for learning new digital technologies and front-end development. I created this website to track my journey and share things I've learned along the way. I am a husband, father, pet lover and currently work at Amazon Web Services (AWS) doing digital marketing.