Skip to main content
A newsletter signup is one of the highest-ROI additions to any site — it converts passing traffic into an audience you actually own. This guide walks through three ways to add one.

Easiest

Ask the AI assistant

Visual

Use a pre-built section

For developers

Build from scratch

Option 1: Ask the AI Assistant

1

Open the AI chat

Click the AI tab in your project.
2

Describe what you want

Add a newsletter signup form to the footer of my site. 
Save submissions to the `newsletter_subscribers` table.
3

Review and refine

The AI adds the form, creates the table if it doesn’t exist, and wires up the API handler. Ask for tweaks:
  • “Make it a two-column layout”
  • “Add a consent checkbox”
  • “Show a thank-you message inline instead of redirecting”
4

Deploy

Click Deploy to push the changes live.

Option 2: Use a Pre-Built Section

1

Open the visual editor

Go to your project and click Edit on any page.
2

Open the Sections panel

In the left sidebar, click Sections. Scroll to the Newsletter category.
3

Drag and drop

Drag a newsletter section onto the page where you want it — footer, sidebar, end-of-post.
4

Configure the fields

Click the section to open the inspector. Adjust:
  • Headline and subtext
  • Field labels (Name, Email)
  • Button text
  • Thank-you message
  • Styling (background, button color)
5

Save and deploy

Click Save, then Deploy.

Option 3: Build From Scratch

If you want full control, you can write the form component directly.
1

Create the database table

In Database > Tables, create newsletter_subscribers:
CREATE TABLE newsletter_subscribers (
  id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
  email text UNIQUE NOT NULL,
  name text,
  source text,
  subscribed_at timestamptz DEFAULT now(),
  confirmed_at timestamptz
);
2

Build the form component

<form method="post" action="/api/subscribe">
  <input name="email" type="email" required placeholder="Your email" />
  <input name="name" type="text" placeholder="Your name (optional)" />
  <label>
    <input type="checkbox" name="consent" required />
    I agree to receive occasional emails.
  </label>
  <button type="submit">Subscribe</button>
</form>
3

Write the API handler

Create an API route at /api/subscribe that:
  1. Validates email format
  2. Inserts into newsletter_subscribers
  3. Sends a confirmation email (if using double opt-in)
  4. Returns JSON ({ success: true } or error)
4

Sync to your ESP

Use a workflow to push new subscribers to your email service. See Connect Mailchimp for the pattern.

Double Opt-In

Double opt-in is strongly recommended — it boosts deliverability, filters typos, and is required in several jurisdictions (Germany, Canada). Flow:
  1. User submits form → row created with confirmed_at = NULL
  2. Send confirmation email with a tokenized link
  3. User clicks link → GET /api/confirm?token=... → update confirmed_at = now()
  4. Only subscribers with confirmed_at IS NOT NULL count as “active”
See Send Emails for the email-sending setup.

GDPR-Compliant Patterns

  • Explicit consent checkbox, not pre-checked
  • Clear privacy policy link next to the submit button
  • Unsubscribe link in every email you send
  • Data export and delete path (users can request their data or deletion)
Never pre-fill fields with cookies or third-party data without explicit consent. Pre-filled forms and pre-checked consent boxes are GDPR violations and drive immediate unsubscribes and spam complaints.

Form Placement Best Practices

PlacementIntentNotes
FooterLowAlways present, low friction
Exit intent popupHighRight moment, but annoying if overused
End of blog postHighReader just finished your content
SidebarMediumConsistent visibility on scroll
Dedicated landingVery highBest for paid traffic
Start with the footer. Add one more placement based on where your readers actually engage.

Incentive Options

Asking for an email without a reason is a hard sell. Offer something:
  • Lead magnet — PDF checklist, template, mini-guide
  • Discount code — 10% off first purchase
  • Early access — beta features, new products
  • Content upgrade — extended version of the blog post they just read
The lead magnet should match the content context. A “Website Performance Checklist” in the footer of a design blog will outperform a generic “Subscribe to our newsletter” by 3-5x.

Syncing to Your Marketing List

Raw subscribers in your database aren’t enough — you need them in your email tool (Mailchimp, ConvertKit, etc.) to actually send to them. See:

Verify It Worked

  1. Submit the form with a test email
  2. Check the newsletter_subscribers table — the row should be there
  3. If using double opt-in, confirm the confirmation email arrives
  4. Click the confirmation link — confirmed_at should populate
  5. Check your ESP (Mailchimp, etc.) — the subscriber should appear in your audience

Troubleshooting

The API route is erroring. Open browser DevTools > Network tab, submit the form, and look at the /api/subscribe response. Common causes: database connection error, unique constraint violation (email already exists), validation failure.
SMTP isn’t configured or the sender domain isn’t verified. Go to Settings > Email — you should see a green checkmark next to your sender domain. If not, see Send Emails for the setup.
Add a UNIQUE constraint on the email column if you haven’t:
ALTER TABLE newsletter_subscribers ADD CONSTRAINT unique_email UNIQUE (email);
Handle the resulting error in your API handler — treat it as a successful subscribe (user is already on the list).
Bots are filling your form. Add a honeypot field (hidden input; real users don’t fill it, bots do) or reCAPTCHA on the form. If volume is extreme, add rate limiting by IP.
The sync workflow isn’t running or is erroring. Go to Workflows > Runs and inspect recent runs. If none exist, the trigger isn’t wired. If they exist but fail, check the error message — usually a bad API key or wrong audience ID.

What’s Next?

Connect Mailchimp

Sync subscribers to your email marketing tool

Welcome Sequence

Send a welcome email series to new subscribers