From e185035138ff45471d2e534a17fef187035ea8c6 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 8 May 2026 18:15:39 +0000 Subject: [PATCH] fix: send subscribe form as urlencoded so Customer.io records form_submit The whats-new subscribe form posts to Customer.io's submit_action endpoint, which expects application/x-www-form-urlencoded (the encoding native HTML form POSTs use). Commit 6cce858 replaced the native submit with a fetch() that sent FormData (multipart/form-data); the endpoint accepts the request and returns the 302, but does not record a form_submit event, so no one is added to the subscriber segment. The opaqueredirect response made the UI report success regardless. Switch the body to URLSearchParams so the request matches the encoding the endpoint actually processes. Add regression tests pinning the body type. --- fern/custom.js | 9 ++++++--- fern/custom.spec.js | 4 ++++ 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/fern/custom.js b/fern/custom.js index 6434797a4..5d9270499 100644 --- a/fern/custom.js +++ b/fern/custom.js @@ -158,12 +158,15 @@ function initializeSubscribeForm() { submitBtn.textContent = 'Submitting...'; var formAction = form.getAttribute('action'); - var formData = new FormData(); - formData.append('email', email); + // Customer.io's submit_action endpoint expects application/x-www-form-urlencoded + // (the encoding native HTML form POSTs use). FormData sends multipart/form-data, + // which the endpoint accepts but does not record as a form_submit event. + var body = new URLSearchParams(); + body.append('email', email); fetch(formAction, { method: 'POST', - body: formData, + body: body, redirect: 'manual', }) .then(function (response) { diff --git a/fern/custom.spec.js b/fern/custom.spec.js index 8b4860837..0a725978c 100644 --- a/fern/custom.spec.js +++ b/fern/custom.spec.js @@ -103,6 +103,10 @@ assert(customJsContent.indexOf("redirect: 'manual'") !== -1, 'custom.js uses fetch with redirect:manual to handle 302'); assert(customJsContent.indexOf('opaqueredirect') !== -1, 'custom.js checks for opaqueredirect response type'); +assert(customJsContent.indexOf('URLSearchParams') !== -1, + 'custom.js sends body as application/x-www-form-urlencoded (URLSearchParams)'); +assert(customJsContent.indexOf('new FormData()') === -1, + 'custom.js does not use FormData (multipart) for the Customer.io submit'); assert(customJsContent.indexOf('subscribe-form-message') !== -1, 'custom.js updates the message div'); assert(customJsContent.indexOf('Thanks for subscribing') !== -1,