Better Way To Embed Active Campaign Forms Into React
Tags: activecampaign, react, embed, webdev
Published: 2019-11-04 02:47:04

---
title: Better Way To Embed Active Campaign Forms Into React
published: true
description: 
tags: active campaign, react, embed, webdev
---

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.