From 3f67194996450d59e021a58a9b1f7414f23fdf8c Mon Sep 17 00:00:00 2001 From: maya shin Date: Wed, 1 Jul 2026 15:23:09 +0200 Subject: [PATCH] fix(newsletter): include hubspotutk (hutk) in HubSpot form submissions Read the hubspotutk cookie and pass it (plus pageUri) in the Forms API context object so submissions link to the correct contact record. Omit hutk entirely when the cookie is absent to avoid INVALID_HUTK errors. --- src/hooks/useNewsletter.js | 21 ++++++++++++++++++--- src/utils/getCookie.js | 9 +++++++++ 2 files changed, 27 insertions(+), 3 deletions(-) create mode 100644 src/utils/getCookie.js diff --git a/src/hooks/useNewsletter.js b/src/hooks/useNewsletter.js index 78101251..d9f109fd 100644 --- a/src/hooks/useNewsletter.js +++ b/src/hooks/useNewsletter.js @@ -1,4 +1,5 @@ import version from '../version/version' +import getCookie from '../utils/getCookie' const PORTAL_ID = import.meta.env.VITE_HUBSPOT_PORTAL_ID const FORM_GUID = import.meta.env.VITE_HUBSPOT_FORM_GUID @@ -7,6 +8,22 @@ const PAGE_NAME = import.meta.env.DEV ? `Mini-dashboard (dev)` : `Mini-dashboard v${version}` +function getContext({ pageName }) { + const context = { + pageName, + pageUri: typeof window !== 'undefined' ? window.location.href : undefined, + } + + // The `hubspotutk` cookie is set by HubSpot's tracking code and ties this + // submission to the visitor's tracked activity and the right contact record. + // Only include `hutk` when the cookie actually exists — HubSpot rejects an + // empty value with INVALID_HUTK, so a cookieless submission must omit it. + const hutk = getCookie('hubspotutk') + if (hutk) context.hutk = hutk + + return context +} + function getBody({ email, pageName }) { return { fields: [ @@ -16,9 +33,7 @@ function getBody({ email, pageName }) { value: email, }, ], - context: { - pageName, - }, + context: getContext({ pageName }), legalConsentOptions: { consent: { consentToProcess: true, diff --git a/src/utils/getCookie.js b/src/utils/getCookie.js new file mode 100644 index 00000000..c97a5f19 --- /dev/null +++ b/src/utils/getCookie.js @@ -0,0 +1,9 @@ +const getCookie = (name) => { + if (typeof document === 'undefined') return undefined + const value = `; ${document.cookie}` + const parts = value.split(`; ${name}=`) + if (parts.length === 2) return parts.pop().split(';').shift() + return undefined +} + +export default getCookie