DEV Community

loading...

Building a newsletter form in GatsbyJS with ConvertKit

Mihai Bojin
Hands-on Engineering Manager with a passion for building and mentoring teams! Technical Leader with expertise designing and developing highly-resilient backend systems for global enterprise companies.
Originally published at mihaibojin.com on ・9 min read

Photo: Typing machine
"Photo by Florian Klauer on Unsplash"

🔔 This article was originally posted on my site, MihaiBojin.com. 🔔


Newsletters are all the rage since 2020! A medium that everyone thought was pretty much extinct is back, stronger than ever!

This fact partly informed my decision to build a site from scratch.

It will serve as the 'top of the funnel' for my newsletter sign-ups.

On to the technical details...

Integrating with an email marketing tool

I chose ConvertKit because I can start free and build it up in time. It's built with the small creator in mind by an Indie Hacker.

I wanted to start building my email list. However, since I don't yet have a lot of content, it didn't make sense to take a too aggressive stance and push newsletter sign-ups on my users.

I decided to add a newsletter form in my site's footer.

GatsbyJS doesn't have a straightforward way to integrate an email marketing tool (or ConvertKit explicitly).

I had two options:

  • write a simple HTML form myself and post directly to ConvertKit
  • write a React component to display ConvertKit's Javascript-based form

I settled on the latter since it had nicer UX and a few extra features built-in, which I'll be discussing below.

Since Gatsby pre-renders all pages, you can't directly include a script tag - it would be interpreted at build time and would not work for the end-user.

The solution was to use the DOM to create a script element and display it.

Here is the component's code:

import * as React from "react";
import { Component } from "react";

class Newsletter extends Component {
  componentDidMount() {
    const script = document.createElement("script");
    script.src = "CONVERTKIT-FORM-URL";
    script.async = true;
    script.setAttribute("data-uid", "CK-UID");
    this.instance.appendChild(script);
  }

  render() {
    return (
      <div>
        <h3>Subscribe to my newsletter</h3>
        <div ref={(el) => (this.instance = el)}></div>
      </div>
    );
  }
}

export default Newsletter;
Enter fullscreen mode Exit fullscreen mode

ConvertKit

Once I finished the coding part, I had to customize ConvertKit.

I didn't want to use my personal Gmail as the sender of the newsletter, but I also did not want to set up a separate account or pay for email hosting.

Email forwarding

I created a simple email forwarding rule in https://forwardemail.net to forward all emails to my Gmail account.

The first step in that process is to verify you own the domain. After creating an account, I updated my domain's DNS records.

I manage all my domains through https://cloudflare.com, and I automate any management operations using https://www.terraform.io/.

I won't go into Terraform low-levels (their documentation is excellent), but here is the configurations I use:

variable "zone_id_com_mihaibojin" {
  default = "GET-THIS-FROM-CLOUDFLARE"
}

resource "cloudflare_record" "com_mihaibojin_mx1" {
  zone_id = var.zone_id_com_mihaibojin
  name = "@"
  value = "mx1.forwardemail.net"
  priority = 10
  type = "MX"
}

resource "cloudflare_record" "com_mihaibojin_mx2" {
  zone_id = var.zone_id_com_mihaibojin
  name = "@"
  value = "mx2.forwardemail.net"
  priority = 20
  type = "MX"
}

resource "cloudflare_record" "com_mihaibojin_forwardemail_spf" {
  zone_id = var.zone_id_com_mihaibojin
  name = "@"
  value = "v=spf1 a mx include:spf.forwardemail.net -all"
  type = "TXT"
}

resource "cloudflare_record" "com_mihaibojin_forwardemail_ver" {
  zone_id = var.zone_id_com_mihaibojin
  name = "@"
  value = "forward-email-site-verification=GET-THIS-FROM-FORWARDEMAIL"
  type = "TXT"
}
Enter fullscreen mode Exit fullscreen mode

Updated your domain's DNS is then a simple command away!

terraform plan && terraform apply
Enter fullscreen mode Exit fullscreen mode

Configuring ConvertKit

After I configured email forwarding and verified I could receive emails, it was time to set up ConvertKit. After adding my email, I waited for the confirmation email and clicked the provided link.

SPF and DKIM

I also set up "Sender Policy Framework" (SPF) and "Domain Keys Identified Mail" (DKIM). Read more here about why it's essential to verify your sending emails (spoiler alert: primarily so that your emails don't end up as Spam).

Once again, I used Terraform to automate this step:

resource "cloudflare_record" "om_mihaibojin_convertkit_cname1" {
  zone_id = var.zone_id_com_mihaibojin
  name = "ckespa.mihaibojin.com"
  value = "spf.dm-2m2gkx6y.sg7.convertkit.com"
  type = "CNAME"
}

resource "cloudflare_record" "com_mihaibojin_convertkit_cname2" {
  zone_id = var.zone_id_com_mihaibojin
  name = "cka._domainkey.mihaibojin.com"
  value = "dkim.dm-2m2gkx6y.sg7.convertkit.com"
  type = "CNAME"
}
Enter fullscreen mode Exit fullscreen mode

DMARC

I went the extra mile and also configured DMARC. By all accounts, you shouldn't bother when you're not sending a large volume of emails, but I wanted to start right and be prepared for future success!

One of DMARC's policy settings is p=none, which means data will be collected but not actioned - this is what you want in this scenario.

To monitor collected data, I created an account on https://dmarcian.com/. They provide a service that analyzes your data and reports on any threats.

Here is how the DNS record configuration for DMARC looks like in Terraform:

resource "cloudflare_record" "com_mihaibojin_dmarc" {
  zone_id = var.zone_id_com_mihaibojin
  name = "_dmarc.mihaibojin.com"
  value = "v=DMARC1; p=none; rua=mailto:GET-THIS-FROM-DMARCIAN;"
  type = "TXT"
}
Enter fullscreen mode Exit fullscreen mode

You can follow these resources for more information:

GDPR and newsletter sign-ups

I wrote about privacy and GDPR in the European Union in my privacy-friendly analytics article.

ConvertKit has an option to allow users to explicitly opt-in for features that fall under GDPR's guidelines. However, the outcome is that users will be redirected to a separate page after sign-up.

By default, ConvertKit sends users to https://app.convertkit.com/confirm-subscription. Since that takles the user away from my site, I replicated the same message at https://mihaibojin.com/confirm-subscription so that users can navigate back to the homepage or some other article!

The URL can be configured for each form created in ConvertKit, by going to Settings -> Incentive and adding the URL.

Conclusion

I hope you found this post useful. If you have any thoughts or comments, please share your thoughts on this thread.

That's all for now. In the future, I may drop the ConvertKit Javascript code and implement an HTML form since I'm not particularly fond of tracking JS running on my site.

Until then, stay safe!


If you liked this article and want to read more like it, please subscribe to my newsletter; I send one out every few weeks!

Discussion (0)