Skip to content

feat(newsletter): JSONP submission + plumb VITE_MAILCHIMP_URL through deploy#32

Merged
igorhasse merged 1 commit into
mainfrom
feat/newsletter-jsonp
Apr 28, 2026
Merged

feat(newsletter): JSONP submission + plumb VITE_MAILCHIMP_URL through deploy#32
igorhasse merged 1 commit into
mainfrom
feat/newsletter-jsonp

Conversation

@igorhasse
Copy link
Copy Markdown
Owner

Summary

Form was redirecting to a blank Mailchimp hosted signup page ("There are errors below") instead of subscribing inline. Two issues bundled:

  1. Newsletter component switched from HTML form POST to JSONP. No more `target="_blank"`, no more Mailchimp hosted page. Submits via injected `<script src>` tag, awaits callback, sets state inline. Treats "already subscribed" as success.

  2. Honeypot field name derived from URL. Was hardcoded `b_b996de87...`; now extracted from `u` and `id` query params of `VITE_MAILCHIMP_URL`. Forks just swap the env var and the component works.

  3. deploy.yml passes `VITE_MAILCHIMP_URL` to the build env. Required so the URL is inlined into the Worker bundle on prod.

Action required from you (one-time)

Before merging, run:

```bash
gh secret set VITE_MAILCHIMP_URL --body 'https://gmail.us20.list-manage.com/subscribe/post?u=b996de87ad64788a889762e4f&id=bb87ce3968&f_id=007102eef0'
```

Test plan

  • Local (`yarn dev` with `.env.local` set): submit a real email. Form should NOT open a new tab. Button text should change "Assinar →" → "enviando…" → "obrigado ✓". Email arrives in Mailchimp audience.
  • Submit the same email twice. Second time should also land on "obrigado ✓" (already-subscribed treated as success).
  • Submit with `VITE_MAILCHIMP_URL` unset (or invalid). Should land on the "Configure VITE_MAILCHIMP_URL no .env..." error message.
  • After merge: ensure GitHub secret is set; verify in prod that submitting actually adds to Mailchimp.

🤖 Generated with Claude Code

… deploy

The Mailchimp embed form was doing a standard HTML form POST with
target="_blank", which opens the Mailchimp hosted signup page in a new
tab. Worse: in some browsers the EMAIL field never made it to the
hosted page (likely because React's setState("loading") races with the
browser packaging the form data, and a disabled input stops contributing
to the FormData), so users landed on a blank Mailchimp form with
"There are errors below — Please enter a value."

Switched to JSONP. The form now:

- Calls preventDefault() on submit (no more navigation away)
- Builds the JSONP URL from VITE_MAILCHIMP_URL by replacing
  /subscribe/post → /subscribe/post-json
- Adds EMAIL=<typed>, the honeypot field b_<u>_<id>=<empty>, and a
  callback name c=mc_cb_<timestamp>_<rand>
- Injects a <script src=...> tag, awaits the JSONP callback
- On success → state "done"; on already-subscribed → also "done";
  on any other response or script error → "error" with config message

The honeypot field name is now derived from the action URL's u/id query
params (no more hardcoded "b_b996de87..."), so the component works
verbatim for any fork that swaps VITE_MAILCHIMP_URL.

deploy.yml now passes VITE_MAILCHIMP_URL into the build step env so the
URL is inlined into the Worker bundle on prod deploys. User still has
to run `gh secret set VITE_MAILCHIMP_URL ...` once for the secret to
exist.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@igorhasse igorhasse merged commit b7c80cd into main Apr 28, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant