Guides

Forms, pop-ups and Magic Links

Put a signup form on any site, bring in readers from other newsletters with one link, and keep track of where every subscriber came from.

Signup forms for other sites

Make a form on the Forms page or with create_form: a name, the button's words, up to 5 of the newsletter's custom fields after the email (a first name is a custom field), colors that start from the newsletter's accent color, and what happens after a signup: a message, or a page of yours to go to. A newsletter has up to 20 forms. Every form is a page on the newsletter's own host, and the Forms page gives you the code for it.

One line. It puts the form where the script stands, in a frame that sets its own height as the form changes. The frame only listens to messages from the newsletter's host and only to its own frame, and the only things it can ask for are a height and, if you chose a page to go to, that page.

Any page
<script async src="https://your-slug.example.com/embed.js" data-flockstack-form="FORM_ID"></script>

Plain HTML. For a site that doesn't allow scripts or frames: a form that posts to the form's address. The visitor lands on the form's page with the result, or on your own page if you set one. The hidden field is a trap for bots: leave it empty and out of sight.

HTML form
<form action="https://your-slug.example.com/f/FORM_ID" method="post">
  <input type="email" name="email" placeholder="you@example.com" required>
  <input type="text" name="website" tabindex="-1" autocomplete="off" aria-hidden="true" style="position:absolute;left:-10000px">
  <button type="submit">Subscribe</button>
</form>

From a script of your own. The same address takes JSON, from any site: it answers { "ok": true } or { "ok": false, "error": "…" }. For a form you build entirely yourself, add_contact with a signups only key does the same.

JSON
curl -X POST https://your-slug.example.com/f/FORM_ID \
  -H "Content-Type: application/json" \
  -d '{"email":"jane@example.com","utm_source":"my-site"}'

What a signup goes through

The same checks as the signup form on the website. The newsletter's confirmed opt-in applies, so a new address gets the confirmation email and joins when it clicks; addresses that bounced, complained or unsubscribed stay out; throwaway and misspelled addresses are refused; and a visitor can sign up 5 times in 10 minutes. Anyone can post to a form, which is what makes it embeddable, so the address sets and reads no cookie and answers every origin without credentials. The protection is the confirmation email, the honeypot and the limits, not who posted.

A form's page can be framed by any site; no other page of a newsletter can. Contacts made through a form have the source form:<id>, with the page that holds the form as their referrer.

Views, signups and conversion

A form counts its views when its page loads, on the server, so there is no script of ours on the site that shows it. Crawlers and link previews don't count, and a visitor loading it over and over stops counting after 60 loads in 10 minutes. Counts are kept as one row for each form and day (UTC), not one per view. Signups are new contacts, pending ones included; conversion is signups over views. get_form has the days.

The website's pop-up

A newsletter's website shows a signup form over an issue. Set when on the Pop-up page or with update_popup_settings: after some seconds (3 to 300), once the reader is a share of the way down the page (45% unless you change it), or when the mouse leaves through the top of the window, on desktop only; and on issue pages, the front page, or those and the author's page. Closing it keeps it away for 14 days unless you set another number. That, and whether the reader already signed up in their browser, are flags in the browser's own storage: no cookie, and nothing is sent to us. It never opens for someone who signed up there or is signed in to the website. It opens in a dialog that traps the keyboard focus, closes with Escape and doesn't animate for readers who ask for less motion.

Gating issues. Turn on the gate to show every issue but the newest few (1 by default) as its first part of the text (30% by default, plain text) followed by the signup form. A subscriber who is signed in to the website reads it whole: a reader signs in through the link in the email we send them when they confirm their address, or through "Already subscribed? Email me a link" on the issue. The sign-in works once, for 30 minutes, and then the browser keeps a session for 30 days. The website's RSS feed carries the same beginning with a link, and a paid issue keeps its own teaser. The gate hides text from search engines and readers who haven't subscribed; it is not a login for secrets.

Magic Links

A Magic Link is one address that subscribes a reader in one click, from a link in another newsletter or in an automation. The other platform fills in each reader's email address when it sends, so the reader doesn't type anything. Get yours from the Forms page, under Magic Links, or with get_magic_link: it has {{email}} where the address goes.

In another newsletter. Ask the newsletter you swap with to use it as a button or link in their issue, and to put their platform's own merge tag for the reader's email address where {{email}} stands: Mailchimp's is *|EMAIL|*, Kit's {{ subscriber.email_address }}, FlockStack's {{email}}. Add utm_source and utm_campaign to see which swap brought whom. A + that their platform doesn't encode still reaches us as the address.

A swap with a Mailchimp newsletter
https://your-slug.example.com/subscribe/magic?email=*|EMAIL|*&k=1&sig=…&utm_source=their-newsletter&utm_campaign=swap-12

In an automation. Any email you send from another tool, such as a thank-you after a purchase or a webinar reminder, can carry the link with that tool's merge tag. Tools that call the API can use add_contact instead, which tells you what happened.

What keeps it safe. The link is signed for your newsletter and a key id, not for an address, because the other platform writes the address. That means anyone who has the link could try an address that never asked. So with confirmed opt-in on, which is the default, the address only gets your confirmation email and joins when it clicks it. An address can be tried 3 times a day and a network 10 times in 10 minutes, on top of the signup limit of 5 in 10 minutes. A reader who unsubscribed is never brought back by it, only by signing up on your website. The page opens without subscribing anyone until a browser runs it, so link scanners don't subscribe readers who never clicked. If the link ends up where it shouldn't, retire it: the old one stops working at once and you get a new one. With confirmed opt-in off, anyone with the link can subscribe any address, and the dashboard warns you.

Where signups come from

Each new contact keeps where it came from: the UTM parameters of the address the visitor arrived by (utm_source, utm_medium, utm_campaign, utm_term, utm_content), the host of the page that linked to the form, and a channel FlockStack works out: direct, search, social, email, paid, another website, a recommendation or your referral program. The newsletter's website holds the parameters in the browser's own storage for 30 days, so a reader can look around before signing up; the first signup's attribution is the one kept. A form in a frame gets the UTM parameters of the page that holds it.

A signup form of your own can pass utm and referrer to add_contact. A newsletter can also add utm_source (its name), utm_medium=email and utm_campaign (the issue's slug) to the links in its issues that lead to other sites: turn on UTM tags on links in the newsletter's settings. A link that already has UTM parameters keeps them.