Skip to main content
vibestrap ships a newsletter module with two providers: Resend (default, syncs to a Resend Audience) and Beehiiv (full publishing platform with double opt-in and broadcast scheduling). The signup form lives in the home page footer; a server action validates the email and dispatches via the active provider.

Prerequisites

  • For Resend: a Resend account, API key, and an Audience created in the dashboard.
  • For Beehiiv: a Beehiiv publication and an API key from Settings → Integrations → API.
  • The newsletter feature flag (siteConfig.newsletter.enable) set to true.

Step-by-step (Resend)

  1. Create an Audience at resend.com/audiences. Copy its ID — looks like aud_xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.
  2. Set env vars in .env.local:
    RESEND_API_KEY=re_xxxxxxxxxxxx
    RESEND_AUDIENCE_ID=aud_xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
    
  3. Confirm the config in src/config/site.ts (Resend is the default):
    newsletter: {
      enable: true,
      provider: 'resend',
    },
    
  4. Restart pnpm dev. Submit the footer signup form — the contact should appear in your Resend Audience within seconds.

Step-by-step (Beehiiv)

  1. Get your publication ID from Beehiiv → Settings → Integrations. It’s shaped like pub_xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.
  2. Set env vars in .env.local:
    BEEHIIV_API_KEY=bv_xxxxxxxxxxxx
    BEEHIIV_PUBLICATION_ID=pub_xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
    
  3. Switch the provider in src/config/site.ts:
    newsletter: {
      enable: true,
      provider: 'beehiiv',
    },
    
  4. Configure double opt-in inside Beehiiv (Settings → Subscribers → Confirmation). vibestrap passes reactivate_existing: true and send_welcome_email: false, leaving Beehiiv to send the confirmation email per your publication’s policy.

Pick the right provider

ProviderWhen to pick
ResendYou already use Resend for transactional mail, you want one less vendor, and a basic Audience is enough.
BeehiivYou want a real newsletter product — landing pages, paid subs, referrals, broadcast scheduling, analytics.

Verify it works

  1. Submit the footer signup form with a fresh email.
  2. Resend: check the Audience in the Resend dashboard — the contact should be there with unsubscribed: false.
  3. Beehiiv: check Subscribers → All — the email should appear with status pending (until they click the double-opt-in link) or active if you’ve disabled confirmation.
  4. Submit the same email again. Both providers handle this gracefully (Resend dedupes; Beehiiv reactivates) — no error toast should appear.

Common pitfalls

  1. Resend: missing RESEND_AUDIENCE_ID. The provider silently no-ops when either env var is unset (logs [newsletter/resend] Skipped in dev). Form submissions look successful but nothing is stored. Always check both env vars are set in production.
  2. Beehiiv: reactivate_existing behaviour. If a contact previously unsubscribed, vibestrap reactivates them on the next signup. Some jurisdictions require a fresh opt-in for re-subscription — flip the flag in src/newsletter/provider/beehiiv.ts if your legal team objects.
  3. GDPR for EU traffic. Use Beehiiv with double opt-in enabled (the default) and add a consent checkbox to the form. Resend Audiences default to single opt-in; you’ll need to wire your own confirmation email if you sell to EU customers.
  4. Same key, different env. Public Resend keys are per-environment. The same RESEND_AUDIENCE_ID may not exist in both your dev and prod Resend projects — keep two audiences or use the same project across both.
  5. Switching providers. Existing subscribers in the old provider stay there. There’s no automatic migration — export from the old, import to the new.

Add an inline form anywhere

The form is a server action. Mount it wherever — a blog sidebar, a CTA section, a modal. Look at the home page footer for the existing usage, copy the component, and the server action will route through the active provider automatically.

Official docs