Skip to main content

The most annoying thing about static site generators: FIXED

TL;DR: I wanted to write pure HTML forms without having to write the form backend. I selected FormKeep in conjunction with our static site generators to create a lean, clean workflow.


Having to write a form back end sucks.

In hacking around on the web for more than 15 years, I’ve built countless bespoke landing pages, lead capture forms, and emails for direct marketing initiatives. In the simplest cases, I’ve had access to marketing automation systems that take the mundane task of setting up campaign-specific forms and…well, basically make it mundane or cumbersome in a different way.

And then I came across a new challenge with building forms.

Static site generators are great…

I only started using static site generators recently to create marketing landing pages, and the speed and efficiency is a huge improvement over my old methods. (The marketing site at Customer.io is built with Middleman, a Rails-based static site generator. It’s swell. So is Jekyll, which we use for our technical docs.)

Static site generators are easy to set up if you’re not afraid of Terminal, enjoy a bit of tinkering, and don’t want the bloat of popular web-based content management systems. Even better is that you have access to gobs of Ruby Gems that give you the ability to quickly extend your site in useful ways.

…and static site generators can also be annoying

However, I encountered a problem that I never imagined I’d run into again: not having a database to send my leads to now that I work for a company that isn’t running a traditional marketing automation system. The downside of static site generators is that — by design — you’re missing the database to store metadata, content change logs, and form submission data. The easy solution is to use a few point solutions to manage some of the operations traditionally handled server-side — like form submissions. If you’re a growing company, I’ll bet you’re already doing some (okay, a lot) of that.

As the demand gen person at Customer.io, handling lead flow is part of my job, so I’ve had to figure out how to route form data to our data warehouse. For the last year, I’ve been relying on Unbounce to create and serve our marketing landing pages — which, for all intents and purposes, has been a good experience. Pages are quick to deploy, test, and report on. They have webhooks, which makes data super easy to send to Zapier.

But I wanted more control over the form code itself. I wanted to inject front matter from the static site generator, field validation, and control form field names and IDs with pure HTML, not a WYSIWYG.

Getting more control over forms — efficiently

In order to get the level of control I craved over our lead forms, to fold our landing pages into the rest of the marketing site for a more consistent brand experience, and to do so in a way that fit into our current measurement ecosystem—I needed to find a point solution that would send form data directly where I wanted it.

Fast forward to FormKeep. Super simple implementation and integration: submit your form data to their endpoint, then forward it on to Zapier with their integration.

FormKeep gives you a form endpoint, and integrates with Zapier

This allows me to use the power of the static site generator’s front matter for building modular forms, plus I can segregate various data use cases by using a new form endpoint (e.g., sales contact forms vs. landing page forms).

Form action URL is provided by Formkeep. Dynamic values provided by Middelman Frontmatter. This enables the re-use of form code for my various landing pages.
Select the form for your zap trigger (Super useful, although do wish they had an “all forms” option)

Bonus points for dynamic redirects!

FormKeep gets bonus points for allowing me to build in dynamic redirects (or per-page) with a JavaScript snippet and an extra hidden field. Here’s the rundown for Middleman pages (Jekyll would only be slightly different).

Set up your frontmatter to include an action/redirect URL…

---
title: my cool page
action: https://customer.io/features
---
My awesome content

Then add a hidden field to your form code…

<input type="hidden" name="_redirect_url" id="redirect" value="">

…where name="_redirect_url" is what FormKeep relies on to redirect the user on form submission.

And one last step to populate the value attribute…

<script type="text/javascript">
 var action = "https://customer.io#{@page.action}";
 $("#redirect").val(action);
</script>

…where #{@page.action} is the Middleman variable used to pull the action frontmatter from the markdown page and assign it to the JavaScript action variable.

Here’s how: start to finish

  1. Define consistent frontmatter data in your markdown, including a redirect URL
  2. Set up a form partial and call your frontmatter variables by name
  3. Set up a new form, or grab an existing form endpoint from FormKeep and add it to the action form attribute
  4. Include all hidden fields, including your redirect URL using the special name attribute provided by FormKeep
  5. Include your form partial in your page layout/template
  6. Add the JavaScript snippet to populate the redirect URL in the template

Boom! I get the control I want without the headache of writing a form backend or dealing with the bloat of a traditional marketing automation system or CMS. This is one of the things I enjoy most about working in this field — tinkering with a host of very specific tools to build out exactly what I need for an efficient workflow.

Next up: better email validation

I’m always looking for more ways to optimize, so the next cool trick I want to implement with forms is the BriteVerify service, whose API tests for the existence and validity (think beyond RegEx validation) of an email address and gives the end user feedback if they miskey their email. I’ll let you know how it works out!

In the meantime, hit the comments with your bright ideas: how do you pimp out your static site generator? And if you try out the form solution I’ve described, let me know how it works for you!