Docket / Learn / Email capture

Email capture audit

Is your site actually collecting email, or does it only look as though it is? Docket has a check called Email list buildingmar.email_capture, in the Tracking & campaign readiness lane — and the honest answer is that it settles a much smaller question than its name suggests.

Here is the whole of it. The check stands down if an email tool's tag is already on the site. Otherwise it reads the opening of each page's body copy, plus the text of its buttons and of any link that reads as a call to action, and looks for any of a short list of words. If it finds one, it says nothing. If it finds none, it reports that no email capture was seen. It never looks at a form.

What it actually does, in order

First, language. The phrase list is English, so the check asks ctx.prose_language_supported and returns immediately on a site whose prose is in another language. That gate exists across the codebase because English phrase lists, run against a site that is not in English, find nothing and report the absence as a fact.

Second, the tag. It collects the site's trackers and stops if any of Klaviyo, Mailchimp, HubSpot is among them. That set is not a shortlist of good tools — it is every email platform the tracker table can recognise, all 3 of them. A site running any other email service gets no credit for it here and falls through to the word search.

Third, the words. It walks the first 40 indexable pages and, for each, joins the opening of page.text to that page's call-to-action strings, lowercases the result, and tests it against these:

The test is a plain substring match, and one hit anywhere stops the scan.

Fourth, the site's size. Even with nothing found, the finding is suppressed unless the crawl saw at least 5 indexable pages, so a smaller site is never told it has no email capture.

What comes out, when all of that lines up, is a low-severity finding with a small effort estimate. It is also marked as requiring a full crawl, which means the report drops it when the crawl was degraded rather than presenting an absence gathered from a handful of pages as a fact about the site.

It does not look for a form

This is the part worth carrying away, because the check's name argues against it.

page.text is built by dom.main_text(), whose docstring reads "Body text minus nav/header/footer/aside/form". The footer and the form element are two of the regions it discards. So the signup box in your footer — the one with the email field and the button — sits inside the two regions this field is defined to discard. Its words are not in page.text at all.

The one route that survives is page.ctas, which is collected from anchors, buttons and submit inputs anywhere in the document. If your footer button says Subscribe, the word arrives that way. If it says Go, or Send, or it is an arrow icon with no text, nothing arrives and the form is invisible to this check however well it works.

The inverse is just as true. A page carrying an <input type="email"> and the sentence "we will let you know when it is back in stock" has a working capture and none of the listed words, and the check will report it as missing. A blog post about how to write a newsletter has no capture at all and will pass.

A substring match is a loose match

The comparison is phrase in low — a bare substring, not a word-boundary match. The same codebase has a recorded incident about exactly this shape elsewhere: a boundary matcher was written for the call-to-action list after ordinary footer links were counted as calls to action, and the first example in that comment is that Unsubscribe contains subscribe. That fix was applied to the CTA vocabulary. This check still compares the plain way.

So a page that says "unsubscribe at any time", or links to a subscriber agreement, satisfies the search. The error runs in the direction of silence: the check finds a word, concludes there is a capture, and says nothing. Nothing is reported, nothing looks wrong, and the finding you did not get is the one you cannot act on.

What it cannot tell you

Lead with this, because it is most of the answer to the question at the top.

Docket reads markup. It can observe that a word is present on a page it fetched. It cannot observe anything on the other side of the form: whether a visitor ever completes it, whether the address is written anywhere, whether the endpoint the form posts to still exists, whether a confirmation mail is sent, or whether the list has been mailed once since the day it was created. A capture that quietly drops every address into a disconnected inbox reads, from the markup, exactly like one that works.

It also says nothing about how many people sign up, and this page will not estimate it. No rate appears here, because none was measured — and a number attached to somebody's signup form by a tool that has never seen a single visitor session is an opinion wearing a decimal point.

The check itself is less careful about that boundary, and the honest thing is to show you where. Its fix text, verbatim from the source, reads:

Add a single email capture with a real reason to subscribe — a useful guide, a price list, an availability alert. A bare 'subscribe to our newsletter' converts poorly; offering something specific converts well.

The first sentence is a mechanical instruction and the check can support it. The second is advice. The check measured no conversion rate on your site or on anyone's, and you should read that sentence as the opinion of whoever wrote the check rather than as a finding.

Why the check exists at all, stated mechanically

The reason to have a capture is not a statistic. It is that search results, social feeds and ad auctions are all addressed to you by somebody else's system, and a mailing list is addressed by yours. When a ranking moves or an account is suspended, the list is the only route to the same people that does not go through the thing that changed. That is a property of who owns the address book, and it is true without any figure under it.

Where the nearby checks pick up

Two of them are worth knowing about, because each answers something this one does not.

The tag half of this check reads the same tracker table as the rest of the lane, and that table is what the coverage checks work from — whether the tags you believe are running appear on every page rather than on the template they were added to. The tracking lane, and the coverage question it is built around.

The form half belongs to a different lane entirely. cvr.no_capture is the check that does count forms, and mailto:, tel: and sms: links, and anything labelled contact, enquire, book or support — and it fires at high severity when a site has none of them. Its question is whether a visitor can reach you at all, not whether you are building a list. What the conversion lane judges, and what it refuses to judge for you.

Checking this yourself

You do not need the tool for the part that matters, and the part that matters is not the markup. Open your own site on a phone, find the signup, and put a real address into it — one you can read, not the one the form was built to notify. Then wait.

If nothing arrives, you have learned the thing no crawler can tell you. If something arrives, open the list itself and look at the date of the most recent send. A capture feeding a list nobody has mailed in a year is collecting addresses, not building an audience, and no check in any tool will ever report it.

Download Docket

Common questions

Does Docket check whether my newsletter signup form works?

No. The email list building check never inspects a form. It looks for an email platform's tracking tag, and failing that for one of 8 English phrases in your body copy or your button text. Whether the form submits, where the address goes, and whether anyone reads it are all outside what a crawler can see.

Why did Docket say I have no email capture when I do?

Most likely because none of the words it looks for appear near it. The check reads body copy with the nav, header, footer, aside and form regions removed, plus the text of buttons and links. A footer form whose button says Go rather than Subscribe puts nothing in either place, so the capture is real and invisible to this check.

Why did Docket stay quiet when I have no signup anywhere?

Three things silence it. An email platform's tag anywhere on the site; a crawl of fewer than 5 indexable pages; or any page containing one of the phrases as a substring, which includes the word unsubscribe, since it contains subscribe. The check compares plainly rather than on word boundaries.

Will an email list improve my conversion rate?

This page will not tell you, and neither will the check. No conversion rate was measured. The mechanical argument for a list is narrower and does not need a figure: search, social and ad platforms reach your audience through systems you do not control, and a list reaches the same people through one you do.

Does the check work on a site that is not in English?

No, and it says so by standing down. The phrase list is English, so the check returns before doing anything on a site whose prose is another language. Reporting an absence found by an English word list on a site that is not in English would be a fact about the word list, not about the site.