30Newsletter
The subscribe pattern: one email field, one button, the promise in the help line. Both response messages exist in the DOM from the start (hidden) — a live region created together with its message announces nothing. Ghost's data-members-* hooks work as-is.
Use it for
- Blog footers, article ends, the CTA band's form variant
Not for
- Multi-field lead capture — that is a real form with its own page
Inline
The one-liner for article feet and footers.
markup
<form class="ns-field" style="max-inline-size:26rem;inline-size:100%" onsubmit="return false">
<label class="ns-field__label" for="nl-e">Email address</label>
<div style="display:flex;gap:var(--space-2);flex-wrap:wrap">
<input class="ns-input" id="nl-e" type="email" autocomplete="email" placeholder="you@example.com" style="flex:1;min-inline-size:12rem">
<button class="ns-btn ns-btn--primary" type="submit">Subscribe</button>
</div>
<p class="ns-field__help">Weekly Salesforce lessons. Unsubscribe any time.</p>
</form>In the CTA band
The dark band closing a page, with the form as its action.
// newsletter
One lesson a week, in your inbox
markup
<div style="text-align:center;inline-size:100%;max-inline-size:30rem;margin-inline:auto">
<span class="ns-kicker">// newsletter</span>
<h2 style="color:var(--color-on-brand);font-size:var(--size-h3);margin-block:var(--space-2) var(--space-4)">One lesson a week, in your inbox</h2>
<form style="display:flex;gap:var(--space-2);flex-wrap:wrap;justify-content:center" onsubmit="return false">
<input class="ns-input" type="email" aria-label="Email address" placeholder="you@example.com" style="flex:1;min-inline-size:12rem">
<button class="ns-btn ns-btn--white" type="submit">Subscribe</button>
</form>
</div>Success / failure messages
Rendered hidden from the start; JS only flips the hidden attribute.
Check your inbox — the confirmation link is on its way.
That did not work. Check the address and try again.
markup
<p class="ns-field__help" role="status">Check your inbox — the confirmation link is on its way.</p>
<p class="ns-field__error" role="alert">That did not work. Check the address and try again.</p>Accessibility contract
- The label is real; the placeholder is an example, not the label
- Success is role="status", failure role="alert" — pre-rendered, then unhidden