DEV Community

Sara Gibbons
Sara Gibbons

Posted on

Better Way To Embed Active Campaign Forms Into React

Let's face it, embedding scripts in your React app just makes you feel like you need a shower. So when Active Campaign comes along with a form you embed you feel a lot of, "Get outta here!" Even better you have to build it to match a pre-defined style. Yeah, I feel ya.

Realizing we have to deal with this beast we are left with 2 options after we create the form in Active Campaign:

1. Style the form within Active Campaign.

This will most likely mean investing hours of your life fighting with the limited options and custom styles. Sure do able, but for most of us developers out there, this is super frustrating. As you are not just trying to make that more look decent, it needs to match your exact syles, and oh yeah render properly within your site.

For those of you brave enough to travel this path, may the force be with you. If you do, here are my tips:

  • Either use the form for just the form input and submit elements or for the entire form section you are working to build. No gray area here. Limited, or all in.
  • Don't wait to dive into the custom styles. It's really the only way you are going to get anywhere. Get the tags set up that you need, stay organized and might against all urges to reach for the !important... we all know that ends no place good.

When you have your form ready, for the sake of organization give that thing its own React component. It will need to be a React.Component so that you can utilize the componentDidMount function. Here is where you will inject the Active Campaign provided script into the page. You will end up with something like:

class ActiveCampaignForm extends Component {
  componentDidMount() {
    const script = document.createElement('script');

    script.src = 'https://youareawesome.activehosted.com/f/embed.php?id=1';
    script.async = true;

    document.body.appendChild(script);
  }

  render() {
    <div className="_form_1" />
  }
}

In the above script.src is the script provided by Active Campaign and the element rendered is a div with the id of your Active Campaign form you are embedding.

If you try to style the div or rendered form here in your component. Good luck. When the form fully renders from the Active Campaign script it will overrule all you have here. It is custom styles within Active Campaign for nothing.

Now, if your form is pretty basic, no super custom styling, this may be the perfect solution for you. Enjoy it while it lasts. This is also a decent solution to prove that you have all wired correctly in Active Campaign... list, emails, post-submit form, all that good stuff. Just don't get too attached if you have custom styling tasks in your future.

2. Build your own form in React. Post to the URL of the Active Campaign form.

Ok, now we are talking. Full control of your form and styling all within your component. Beyond that, you can keep the user within the experience of your site and not have to bounce then into Active Campaign.

To do this, again, give this beast its own component. It will help with organization, writing tests, plus I like things to have one purpose.

Now, Active Campaign is not going to give you what you need easily. But all the information you will need is baked into the block of "Full Embed" code that they provide. Within that look for the form, you will need the URL the form submits to as well as all the hidden inputs. Here is what this is going to look like:

class ActiveCampaignForm extends Component {
  constructor(props) {
    super(props);

    this.state = {
      formSubmitted: false,
    };

    this.onSubmit = this.onSubmit.bind(this);
  }

  onSubmit(event) {
    event.preventDefault();
    const data = new FormData(event.target);

    fetch('https://youareawesome.activehosted.com/proc.php', {
      method: 'POST',
      body: data,
      mode: 'no-cors',
    })
      .then(response => {
        this.setState({ formSubmitted: true });
        setTimeout(() => {
          this.setState({ formSubmitted: false });
        }, 5000);
      })
      .catch(error => console.log('Request failed', error));
  }

  render() {
    const { formSubmitted } = this.state;

    return (
      <div>
        <h5>Join our mailing list!</p>

        { formSubmitted && (
          <p>
            <strong>THANK YOU</strong> for joining our mailing list!
            <br />
            Check your inbox for a confirmation.
          </p>
        )}

        { !formSubmitted && (
          <form onSubmit={this.onSubmit}>
            <input type="hidden" name="u" value="1" />
            <input type="hidden" name="f" value="1" />
            <input type="hidden" name="s" />
            <input type="hidden" name="c" value="0" />
            <input type="hidden" name="m" value="0" />
            <input type="hidden" name="act" value="sub" />
            <input type="hidden" name="v" value="2" />

            <input
              type="text"
              name="email"
              placeholder="ex: hello@youareawesome.com"
              required
            />
            <input type="submit" value="Submit">
          </form>
        )}
      </div>
    );
  }
}

In the above, I simply built the form I wanted out exactly how I wanted it. Added an onSubmit handler to submit the values entered and set it to send to the URL I found in the provided "Full Embed" code from Active Campaign.

A few things to note:

  • I hit a CORS issue that prevented the fetch from occurring. There may be other ways to solve this, I just reach for adding mode: 'no-cors' to the fetch options to get passed that issue.
  • I opted to add a state here to know if the form was submitted, formSubmitted. I did this so that I could display a message to the user so that they knew their sign up was successful.
  • The catch fo when an error occurs on the submit should really be more sophisticated than a console.log, but hey, we all start somewhere. In my case I'm going to update this to Sentry.captureException(error);.

Now you are off. You have the best of both worlds, a form you can easily and fully style exactly how you need to and the convenience of using an Active Campaign form tied to a list.

Latest comments (2)

Collapse
 
ranran2121 profile image
francesca

how should you "pack" the form data, in case you do not want to use new FormData(event.target)?

Collapse
 
steelwolf180 profile image
Max Ong Zong Bao • Edited

This was exactly what I needed to modify my previous subscription form for ActiveCampaign. I can't image why it took them for this kind of code to be not in their documentations for their clients.