Skip to main content
Craft → HubSpotIntegration guide

Connecting Craft CMS to HubSpot

Craft is a developer-oriented CMS, usually built bespoke by an agency, which means the implementation is whatever that agency decided and nothing is standard. HubSpot is where sales works, so a conversion that never reaches it is invisible to the people who decide what a lead was worth. The join between them succeeds or fails on one thing: whether the contact identity — email, or the hubspotutk cookie reaches the Craft Commerce order before the conversion happens, because HubSpot can only match a conversion it can tie back to a click it recognizes.

Free30 minutesNo obligation

Specific to this pair

Craft CMS to HubSpot: form entries and Commerce orders, one contact

Resolve Craft form entries and Commerce orders to one HubSpot contact by email, reading hubspotutk at submit time, never from a cached template. Send orders from the PHP order-complete listener as closed-won deals or contact properties, and keep one writer per object: the form plugin for contacts, your listener for orders and deals.

Many Craft sites are lead-generation sites first and stores second, which is where HubSpot fits. Two records matter: the form entry, from whichever form plugin or custom controller this build uses, and, if Commerce is installed, the completed order. Both should resolve to one HubSpot contact by email, and the form submission should carry the hubspotutk cookie so HubSpot can attach the visitor's earlier page views and set original source.

The Craft-specific trap is caching. If the form is rendered on a statically cached page, a hidden hubspotutk field baked into the HTML is the same value for every visitor, or empty, and HubSpot stitches strangers' sessions onto one contact. Read hubspotutk at submit time, never from a cached template. Commerce works the same way: send the order from the PHP order-complete listener using the order's email, as a closed-won deal for sales-assisted orders or as a contact property for small ones.

Check which HubSpot route this build already uses before adding one. Form plugins such as Freeform have HubSpot integrations, and a parallel API sync from a custom module creates a second write path the original agency may not know about. Pick one writer per object: the form plugin for contacts, your listener for orders and deals. Refunds should move the deal or update an order-value property, not delete the record.

Craft → HubSpot · what breaks

Why this join usually fails — Craft → HubSpot

  1. 01

    The contact identity — email, or the hubspotutk cookie never reaches Craft

    Craft's template caching and static caching plugins both serve stored output, and because every build is custom, where the capture code lives differs per site. There is no standard place to look.

  2. 02

    Every install is bespoke

    There is no standard Craft setup, so an approach that worked on another Craft site may have nothing to attach to on this one. Read the build before quoting.

  3. 03

    Duplicate contacts

    Two records for one person, each with half the history. Every downstream report is then wrong in a way that looks like a data problem rather than an integration problem.

  4. 04

    Nothing reconciles afterwards

    HubSpot shows the contact record and its timeline. A successful API response means HubSpot accepted the call, not that it resolved to the right contact — open the record and look.

Craft → HubSpot · the fix

What working looks like — Craft → HubSpot

  • The contact identity — email, or the hubspotutk cookie on every order

  • Conversions arriving in HubSpot

    The revenue or conversion lands on the contact record and its associated deal, where sales can see it and where HubSpot's own attribution reporting can use it.

  • Reconciled against the source

    Craft CMS's own records are the reference, not either dashboard.

Craft → HubSpot · architecture

How Craft and HubSpot actually connect

  1. 1

    Craft CMS holds the truth

    Craft installs are bespoke by nature. Establish how this particular build models a completed order before assuming anything transfers from another Craft site.

  2. 2

    HubSpot needs a click to match

    HubSpot needs to resolve the incoming data to an existing contact or create one. Without an email or a hubspotutk it creates duplicates, and duplicate contacts break every report built on top of them.

  3. 3

    The identifier is the bridge

    The contact identity — email, or the hubspotutk cookie, captured at the visit and carried into the Craft Commerce order.

  4. 4

    The event source decides reliability

    Fire from the event listener in PHP rather than a Twig template, which may be cached.

  5. 5

    Deduplication at the destination

    HubSpot deduplicates contacts on email address. Events and property updates against the same contact are idempotent by design, but a second contact created for the same person is not detected, and merging them afterwards is manual work.

Craft → HubSpot · normal or broken

Working vs. broken, side by side — Craft → HubSpot

Normal, not a fault

  • The contact identity — email, or the hubspotutk cookie present on the order

    Visible on the record itself in Craft CMS, not merely captured somewhere on the site.

  • Sent from the Craft Commerce order-complete event

  • Deduplicated correctly

    HubSpot deduplicates contacts on email address. Events and property updates against the same contact are idempotent by design, but a second contact created for the same person is not detected, and merging them afterwards is manual work.

  • Reconciles with the source

    HubSpot's count and Craft CMS's records agree within a few percent over a closed window.

Actually broken

  • The contact identity — email, or the hubspotutk cookie missing on most records

    Craft's template caching and static caching plugins both serve stored output, and because every build is custom, where the capture code lives differs per site. There is no standard place to look.

  • Sent from the browser

    There is no standard Craft setup, so an approach that worked on another Craft site may have nothing to attach to on this one. Read the build before quoting.

  • Counted twice, or not at all

    Two records for one person, each with half the history. Every downstream report is then wrong in a way that looks like a data problem rather than an integration problem.

  • Nobody has reconciled it

    The dashboard shows a number and no one has compared it to Craft CMS.

Craft → HubSpot · diagnose

Diagnostic order — Craft → HubSpot

  1. 01

    Count orders carrying the contact identity — email, or the hubspotutk cookie

  2. 02

    Follow one real conversion end to end

  3. 03

    Read how this specific build handles order completion

    Assumptions carried from another Craft project are the main source of wasted time here.

  4. 04

    Search for the test contact by email after sending

    One record or two? Then check whether the properties landed on the contact or only on the form submission — they are different things and only the first is usable.

  5. 05

    Read the match rate, not the success message

    HubSpot shows the contact record and its timeline. A successful API response means HubSpot accepted the call, not that it resolved to the right contact — open the record and look.

Craft → HubSpot · prove

How it gets proven — Craft → HubSpot

Against Craft CMS's own records, not against either platform's dashboard.

Source of truth

Craft Commerce's order records in your own database, filtered to completed.

  • The contact identity — email, or the hubspotutk cookie confirmed present on a live order.
  • One contact record confirmed, not two, with the property visible on the contact rather than only on the submission.
  • Order custom field confirmed populated on an order placed as an anonymous visitor through cache.

Craft → HubSpot · free audit

What we check in the free audit

  • Count orders carrying the contact identity — email, or the hubspotutk cookie
  • Follow one real conversion end to end
  • Read how this specific build handles order completion
  • Search for the test contact by email after sending
  • Read the match rate, not the success message

Checked against

Craft Commerce's order records in your own database, filtered to completed.

Get my free conversion tracking audit

Free30 minutesNo obligation

Craft → HubSpot · when not to buy

When you don't need this — Craft → HubSpot

  • If HubSpot already reports conversions that reconcile against Craft CMS's records within a few percent, this join is working and there is nothing to buy.
  • Measure identifier coverage yourself first — pull your last hundred orders and count how many carry the contact identity — email, or the hubspotutk cookie.
  • If the original agency is still engaged, the fastest path is usually specifying the field and having them add the hook.
  • HubSpot's native form and tracking code already handle the straightforward cases well. This is worth building when the conversion happens somewhere HubSpot's code cannot see.

Craft → HubSpot · what we deliver

What gets built — Craft → HubSpot

  • Identifier capture into Craft

    Capture the identifier and store it as a custom field on the order through a Craft event listener, server-side.

  • Event source: the Craft Commerce order-complete event

    Fire from the event listener in PHP rather than a Twig template, which may be cached.

  • Dispatch to HubSpot

    The HubSpot API — contact create-or-update with the properties, or a custom behavioral event where you need the timeline entry rather than a property.

  • Reversals where they exist

    Refunds and cancelled orders are recorded against the order.

Written guarantee

95%+ tracking accuracy

Measured against Craft Commerce's order records in your own database, filtered to completed.. Miss it and we keep working at no cost.

Get my free conversion tracking audit

From $400 · See packages

FAQ

Craft → HubSpot questions, answered

Usually hubspotutk was missing or came from a cached page, so HubSpot couldn't link earlier sessions to the new contact. Check a test submission's contact timeline for page views before the form.

Free · 30 min

Get Craft and HubSpot joined properly

Free30 minutesNo obligation