Skip to content

Conversation

devkiran
Copy link
Collaborator

@devkiran devkiran commented Sep 22, 2025

Summary by CodeRabbit

  • Documentation
    • Added a HubSpot integration guide (Forms + Meetings Scheduler) and a new "Deferred lead tracking" page; documented webhook-based conversion handling.
    • Consolidated per-guide prerequisites into a reusable "Conversion tracking" snippet and removed legacy leads/sales prerequisite sections.
    • Renamed multiple sections to "Quickstart", added a client-side conversion-tracking warning, improved install snippet readability, and updated image alt text and instructional copy.

Copy link
Contributor

coderabbitai bot commented Sep 22, 2025

Warning

Rate limit exceeded

@steven-tey has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 6 minutes and 10 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between cc60cd0 and 5a8f79f.

📒 Files selected for processing (2)
  • concepts/deep-links/deferred-deep-linking.mdx (8 hunks)
  • conversions/leads/deferred.mdx (1 hunks)

Walkthrough

Adds a new HubSpot integration guide at conversions/leads/hubspot.mdx covering HubSpot Forms and Meetings Scheduler lead tracking with Dub (cookie helper, form autofill, Meetings widget message handling, deferred trackLead examples). Also adds conversions/leads/hubspot to docs navigation and replaces many inline prerequisites with a reusable ConversionTrackingPrerequisites snippet across several guides.

Changes

Cohort / File(s) Summary
HubSpot lead tracking docs
conversions/leads/hubspot.mdx
New MDX guide: prerequisites, HubSpot Dub integration setup, create/map dub_id contact property and hidden form field, cookie helper, HubSpot Forms readiness autofill, Meetings widget postMessage handling, and client-side deferred dubAnalytics.trackLead examples.
Prerequisite snippet replacements
conversions/leads/*.mdx, conversions/sales/*.mdx, sdks/client-side/features/conversion-tracking.mdx
Replaced inline LeadsPrerequisites/SalesPrerequisites blocks with a new ConversionTrackingPrerequisites snippet import and component; updated usages across multiple lead/sale integration pages.
Headings, Quickstarts & warnings
conversions/leads/client-side.mdx, conversions/sales/client-side.mdx, sdks/client-side/features/conversion-tracking.mdx, snippets/client-side-tracking-install.mdx
Renamed section headings to "Quickstart" in some pages, added a Warning about client-side limitations, inserted an EnableConversionTracking quickstart component, and reformatted the client-side install script for readability.
New & modified snippets
snippets/conversion-tracking-prerequisites.mdx, snippets/enable-conversion-tracking.mdx, snippets/leads-prerequisites.mdx, snippets/sales-prerequisites.mdx, snippets/dub-client-install.mdx, snippets/client-side-tracking-install.mdx, snippets/leads-intro.mdx
Added conversion-tracking-prerequisites.mdx composing existing snippets; updated enable-conversion-tracking.mdx (intro/tip/duplication issue); removed content from leads-prerequisites.mdx and sales-prerequisites.mdx; changed Card usage to self-closing horizontal in dub-client-install.mdx; small copy change in leads-intro.mdx.
Deferred lead tracking page
conversions/leads/deferred.mdx
New page describing deferred lead workflow with multi-language code examples (JS, Python, Go, Ruby, PHP) showing mode:"deferred" and later qualification steps.
Navigation & metadata
docs.json
Adds "conversions/leads/hubspot" to the Third-party integrations group under Conversion tracking; minor ordering/formatting edits.
Minor copy & alt-text tweaks
conversions/sales/shopify.mdx, conversions/sales/stripe.mdx, sdks/client-side/installation-guides/shopify.mdx, partners/quickstart.mdx, conversions/quickstart.mdx
Small text and alt-text updates, link target change (/partners/white-labeling/partners/embedded-referrals), and minor heading/front-matter edits.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant U as User (Browser)
  participant HS as HubSpot Form
  participant D as Dub Analytics

  rect rgba(200,230,255,0.20)
    note over U,HS: HubSpot Forms — autofill hidden `dub_id` and submit
    U->>U: Read `dub_id` cookie
    HS->>U: Form embed loads
    U->>HS: Populate hidden `dub_id` field when form ready
    U->>HS: Submit form
    HS-->>D: Lead submission includes `dub_id`
  end
Loading
sequenceDiagram
  autonumber
  participant U as User (Browser)
  participant HM as HubSpot Meetings Widget
  participant D as Dub Analytics

  rect rgba(220,255,220,0.20)
    note over U,HM: Meetings Scheduler — deferred lead tracking via postMessage
    HM->>U: postMessage on booking success
    U->>U: Read `dub_id` cookie
    U->>D: dubAnalytics.trackLead(clickId=dub_id, mode="deferred", event="Meeting scheduled", customerInfo)
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • Hubspot #233 — Adds HubSpot integration docs and related navigation entries; likely overlaps directly with the new conversions/leads/hubspot.mdx.
  • Reorganize third-party integrations #234 — Edits to docs.json and conversions/leads navigation; likely overlaps with the navigation/menu changes here.
  • Fix formatting #230 — Overlapping edits to conversions/leads/client-side.mdx (Quickstart/Warning changes).

Poem

I nibble on a dub_id trace,
I hide a carrot in the form's place.
Meetings ping and cookies say,
Little hops track leads each day.
A docs-hop cheer — codes and carrots play! 🥕

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title "Hubspot" is directly related to the primary change in the PR (the addition of a HubSpot lead-conversion integration guide and related docs), so it reflects the main changeset, but it is extremely terse and lacks descriptive context that would help reviewers or future readers.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (4)
conversions/leads/hubspot.mdx (4)

22-22: Grammar nits: pluralize “Form”.

“HubSpot Form help…” → “HubSpot Forms help…”.

-HubSpot Form help you capture lead information and track conversions.
+HubSpot Forms help you capture lead information and track conversions.

39-45: Alt text doesn’t match image content.

Use accurate, descriptive alt for accessibility.

-        alt="Segment Dub (Actions) Mapping"
+        alt="HubSpot Dub Id contact property configuration"

55-62: Alt text mismatch (second image).

Same issue as above.

-        alt="Segment Dub (Actions) Mapping"
+        alt="HubSpot form builder with hidden Dub Id field"

152-192: Meetings postMessage: broaden origin check and harden tracking call.

  • Events may originate from meetings.hubspot.com (new) and historically app.hubspot.com; allowlist both. (community.hubspot.com)
  • Guard if dubAnalytics isn’t loaded to avoid runtime errors.
  • Data shape shown (meetingsPayload.bookingResponse…) matches current community examples, but can change; keep defensive checks. (community.hubspot.com)
-  window.addEventListener("message", function (event) {
-    // Check if the message is from the scheduling widget
-    if (event.origin === "https://meetings.hubspot.com") {
+  window.addEventListener("message", function (event) {
+    const allowedOrigins = ["https://meetings.hubspot.com", "https://app.hubspot.com"];
+    if (!allowedOrigins.includes(event.origin)) {
+      return;
+    }
       const clickId = getCookie("dub_id");
@@
-      if (data.meetingBookSucceeded) {
+      if (data && data.meetingBookSucceeded) {
@@
-        dubAnalytics.trackLead({
+        if (typeof dubAnalytics?.trackLead !== "function") {
+          console.warn("dubAnalytics.trackLead unavailable. Skipping lead tracking.");
+          return;
+        }
+        dubAnalytics.trackLead({
           clickId,
           mode: "deferred",
           eventName: "Meeting scheduled",
           customerExternalId: contact.email,
           customerName: customerName,
           customerEmail: contact.email,
         });
       }
-    }
-  });
+  });
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 68ea300 and ebca86a.

⛔ Files ignored due to path filters (2)
  • images/conversions/hubspot/hubspot-dub-id-property.png is excluded by !**/*.png
  • images/conversions/hubspot/hubspot-forms-setup.png is excluded by !**/*.png
📒 Files selected for processing (2)
  • conversions/leads/hubspot.mdx (1 hunks)
  • docs.json (2 hunks)
🔇 Additional comments (3)
docs.json (2)

76-78: Approve — nav addition conversions/leads/hubspot

hubspot.mdx found at conversions/leads/hubspot.mdx; entry matches the new page path and will render correctly.


87-89: Broken nav link: conversions/sales/hubspot is missing.

File: docs.json — I could not confirm conversions/sales/hubspot.mdx exists (search produced no output); this nav entry will 404 and can break builds. Either remove the entry or add a stub/redirect.

-                  "conversions/sales/segment",
-                  "conversions/sales/hubspot"
+                  "conversions/sales/segment"
conversions/leads/hubspot.mdx (1)

66-106: Form embed snippet: wrong script URL, brittle form selection, and listener ordering.

  • Use HubSpot’s supported v2 embed + hbspt.forms.create; register the hs-form-event:on-ready listener before creating the form and scope it to the specific form via HubSpotFormsV4.getFormFromEvent(event); call setFieldValue on the returned form instance instead of HubSpotFormsV4.getForms()[0].
  • Confirmed code-fence label usage: ```html HTML appears at conversions/leads/hubspot.mdx:70 and conversions/sales/stripe.mdx:146 — CodeGroup uses this pattern elsewhere in the repo.
-    <script src="https://js.hsforms.net/forms/embed/47839131.js" defer></script>
-
-    <div
-      class="hs-form-frame"
-      data-region="na1"
-      data-form-id="YOUR_FORM_ID"
-      data-portal-id="YOUR_PORTAL_ID"
-    ></div>
-
-    <script>
+    <div class="hs-form-frame"></div>
+
+    <script>
       // A helper function to get the value of a cookie
       function getCookie(name) {
         const value = `; ${document.cookie}`;
         const parts = value.split(`; ${name}=`);
 
         if (parts.length === 2) {
           return parts.pop().split(";").shift();
         }
 
         return null;
       }
 
-      // Listen for the form ready event
-      window.addEventListener("hs-form-event:on-ready", (event) => {
-        const clickId = getCookie("dub_id");
-
-        if (!clickId) {
-          console.debug("clickId not found. Skipping lead tracking.");
-          return;
-        }
-
-        // Populate the hidden field with the dub_id
-        HubSpotFormsV4.getForms()[0].setFieldValue("0-1/dub_id", clickId);
-      });
+      // Register the listener BEFORE creating the form
+      window.addEventListener("hs-form-event:on-ready", (event) => {
+        const clickId = getCookie("dub_id");
+        if (!clickId) {
+          console.debug("clickId not found. Skipping lead tracking.");
+          return;
+        }
+        const form = HubSpotFormsV4.getFormFromEvent(event);
+        if (form) form.setFieldValue("0-1/dub_id", clickId);
+      });
     </script>
+    <script charset="utf-8" type="text/javascript" src="//js.hsforms.net/forms/embed/v2.js"></script>
+    <script>
+      hbspt.forms.create({
+        region: "na1", // or "eu1"
+        portalId: "YOUR_PORTAL_ID",
+        formId: "YOUR_FORM_ID",
+        target: ".hs-form-frame",
+      });
+    </script>

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (6)
conversions/leads/hubspot.mdx (6)

22-23: Grammar fix: pluralize “Form”.

“HubSpot Form help…” → “HubSpot Forms help…”.

-HubSpot Form help you capture lead information and track conversions. By integrating with Dub, you can attribute each form submission back to the specific Dub link that drove the conversion.
+HubSpot Forms help you capture lead information and track conversions. By integrating with Dub, you can attribute each form submission back to the specific Dub link that drove the conversion.

41-45: Alt text mismatch (references Segment).

Update alt text to describe the HubSpot property screenshot.

-        alt="Segment Dub (Actions) Mapping"
+        alt="HubSpot Dub Id contact property settings"

56-62: Alt text mismatch (references Segment).

Update to reflect HubSpot form setup.

-        alt="Segment Dub (Actions) Mapping"
+        alt="HubSpot form with hidden Dub Id field"

147-150: Alt text tweak for accuracy.

Clarify what the image shows.

-          alt="Enabling conversion tracking for a workspace"
+          alt="Allowed Hostnames settings in Dub Analytics"

152-156: Consistent terminology: “allowlist.”

Use “allowlist” consistently.

-      You can group your hostnames when adding them to the allow list:
+      You can group your hostnames when adding them to the allowlist:

235-243: PII note (email/name) — add a brief consent reminder.

Since email/name are sent client-side, add a one-line note about obtaining consent where required (GDPR/CCPA).

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e37e2c4 and d49218b.

📒 Files selected for processing (1)
  • conversions/leads/hubspot.mdx (1 hunks)

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (5)
conversions/leads/hubspot.mdx (5)

23-23: Grammar: pluralize “Form”.

Use “HubSpot Forms help you capture…” for subject-verb agreement and consistency with product naming.

-HubSpot Form help you capture lead information and track conversions.
+HubSpot Forms help you capture lead information and track conversions.

41-45: Alt text mismatch (accessibility).

Alt references “Segment” but the image is for HubSpot. Update for accurate, descriptive alt text.

-        alt="Segment Dub (Actions) Mapping"
+        alt="HubSpot contact property for Dub Id (single-line text)"

58-62: Alt text mismatch (accessibility).

Same issue here; adjust to describe the HubSpot form configuration.

-          alt="Segment Dub (Actions) Mapping"
+          alt="HubSpot form builder with hidden Dub Id field mapped to contact property"

174-189: Minor: code fence label.

html HTML” may render oddly in some MDX renderers. Prefer just “html” and use CodeGroup titles if supported.

-    ```html HTML
+    ```html

176-188: Optional: add defensive init for analytics.

If the script is blocked, the queue stub prevents errors, but add a simple ready check before calling methods outside this snippet.

-      })(window, "dubAnalytics");
+      })(window, "dubAnalytics");
+      // Optional: verify queue exists
+      if (!window.dubAnalytics) window.dubAnalytics = function(){(window.dubAnalytics.q=window.dubAnalytics.q||[]).push(arguments)};
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d49218b and 94815cf.

📒 Files selected for processing (2)
  • conversions/leads/hubspot.mdx (1 hunks)
  • docs.json (7 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • docs.json
🔇 Additional comments (3)
conversions/leads/hubspot.mdx (3)

70-107: Use official HubSpot Forms v2 embed and set hidden field in onFormReady.

The snippet loads a nonstandard embed and uses a private API/path (HubSpotFormsV4, "0-1/dub_id"), which is brittle and likely to break. Switch to //js.hsforms.net/forms/embed/v2.js and hbspt.forms.create(...) and set the input by name on onFormReady.

-    <script src="https://js.hsforms.net/forms/embed/47839131.js" defer></script>
-
-    <div
-      class="hs-form-frame"
-      data-region="na1"
-      data-form-id="YOUR_FORM_ID"
-      data-portal-id="YOUR_PORTAL_ID"
-    ></div>
-
-    <script>
-      // A helper function to get the value of a cookie
-      function getCookie(name) {
-        const value = `; ${document.cookie}`;
-        const parts = value.split(`; ${name}=`);
-
-        if (parts.length === 2) {
-          return parts.pop().split(";").shift();
-        }
-
-        return null;
-      }
-
-      // Listen for the form ready event
-      window.addEventListener("hs-form-event:on-ready", (event) => {
-        const clickId = getCookie("dub_id");
-
-        if (!clickId) {
-          console.debug("clickId not found. Skipping lead tracking.");
-          return;
-        }
-
-        // Populate the hidden field with the dub_id
-        HubSpotFormsV4.getForms()[0].setFieldValue("0-1/dub_id", clickId);
-      });
-    </script>
+    <script charset="utf-8" type="text/javascript" src="//js.hsforms.net/forms/embed/v2.js" defer></script>
+    <div id="hubspotForm"></div>
+    <script>
+      function getCookie(name) {
+        const value = `; ${document.cookie}`;
+        const parts = value.split(`; ${name}=`);
+        if (parts.length === 2) return parts.pop().split(";").shift();
+        return null;
+      }
+      window.addEventListener("load", function () {
+        if (!window.hbspt || !hbspt.forms?.create) return;
+        hbspt.forms.create({
+          region: "na1",
+          portalId: "YOUR_PORTAL_ID",
+          formId: "YOUR_FORM_ID",
+          target: "#hubspotForm",
+          onFormReady: function (formEl) {
+            const clickId = getCookie("dub_id");
+            if (!clickId) return;
+            const fld = formEl.querySelector('input[name="dub_id"]');
+            if (fld) fld.value = clickId;
+          },
+        });
+      });
+    </script>

212-247: Harden HubSpot Meetings postMessage handling; don’t rely on meetingBookSucceeded.

Whitelist HubSpot origins (meetings/app), guard payload shape, and read contact from meetingsPayload. This avoids false positives and runtime errors.

-      // Listen for the message event
-      window.addEventListener("message", function (event) {
-        // Check if the message is from the scheduling widget
-        if (event.origin === "https://meetings.hubspot.com") {
-          const clickId = getCookie("dub_id");
-
-          // Get the data from the event
-          const data = event.data;
-
-          if (data.meetingBookSucceeded) {
-            // Get the scheduled contact
-            const contact =
-              data.meetingsPayload.bookingResponse.postResponse.contact;
-
-            if (!contact) {
-              console.debug("contact not found. Skipping lead tracking.");
-              return;
-            }
-
-            // Track the lead with the scheduled contact
-            const customerName = [contact.firstName, contact.lastName]
-              .filter(Boolean)
-              .join(" ");
-
-            dubAnalytics.trackLead({
-              clickId,
-              mode: "deferred",
-              eventName: "Meeting scheduled",
-              customerExternalId: contact.email,
-              customerName: customerName,
-              customerEmail: contact.email,
-            });
-          }
-        }
-      });
+      // Listen for booking messages from HubSpot Meetings
+      window.addEventListener("message", function (event) {
+        const allowed = ["https://meetings.hubspot.com", "https://app.hubspot.com"];
+        if (!allowed.includes(event.origin)) return;
+        const data = event.data && typeof event.data === "object" ? event.data : {};
+        const contact = data?.meetingsPayload?.bookingResponse?.postResponse?.contact;
+        if (!contact?.email) return;
+        const clickId = getCookie("dub_id");
+        const customerName = [contact.firstName, contact.lastName].filter(Boolean).join(" ");
+        dubAnalytics.trackLead({
+          clickId,
+          mode: "deferred",
+          eventName: "Meeting scheduled",
+          customerExternalId: contact.email,
+          customerName,
+          customerEmail: contact.email,
+        });
+      });

176-186: Confirm Dub script attribute contract (“data-domains”) and script URL

  • data-domains must be a JSON string. Supported keys: refer (used/required for partner / client-side click-tracking), site, outbound (string or array). The example data-domains='{"refer":"YOUR_SHORT_DOMAIN"}' is valid; you may prefer the full example: data-domains='{"refer":"refer.dub.co","site":"site.dub.co","outbound":["example.com","example.sh"]}'.
  • Also supported: data-cookie-options (JSON) and data-query-param (optional, default "via"). JSON must be stringified inside the attribute.
  • Verify script src — docs reference https://www.dubcdn.com/analytics/script.js (or variants like script.outbound-domains.js); the snippet’s https://dubcdn.com/analytics/script.conversion-tracking.js may be an older/different variant and should be confirmed/updated.

File: conversions/leads/hubspot.mdx Lines: 176-186

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (4)
conversions/leads/client-side.mdx (1)

32-32: Fix broken link — remove /docs prefix

Replace the site-rooted path in conversions/leads/client-side.mdx:32 (and conversions/sales/client-side.mdx:34) — change /docs/conversions/... to /conversions/.... If you intended the sales guide, use /conversions/sales/introduction.

-For more accurate conversion tracking, consider using [server-side conversion tracking](/docs/conversions/leads/introduction)
+For more accurate conversion tracking, consider using [server-side conversion tracking](/conversions/leads/introduction)
conversions/leads/next-auth.mdx (2)

34-67: Fix undefined variables and cookie API usage in App Router example.

  • user.* is referenced but undefined; should use message.user.*.
  • cookies() is synchronous; remove await.

Apply this diff:

   events: {
     async signIn(message) {
       // if it's a new sign up
       if (message.isNewUser) {
-        const cookieStore = await cookies();
+        const cookieStore = cookies();
         // check if dub_id cookie is present
         const dub_id = cookieStore.get("dub_id")?.value;
         if (dub_id) {
           // send lead event to Dub
           await dub.track.lead({
             clickId: dub_id,
             eventName: "Sign Up",
-            customerExternalId: user.id,
-            customerName: user.name,
-            customerEmail: user.email,
-            customerAvatar: user.image,
+            customerExternalId: message.user.id,
+            customerName: message.user.name,
+            customerEmail: message.user.email,
+            customerAvatar: message.user.image,
           });
           // delete the cookies
-          cookieStore.delete("dub_id");
-          cookieStore.delete("dub_partner_data");
+          cookieStore.delete("dub_id");
+          cookieStore.delete("dub_partner_data");
         }
       }
     },
   },

75-98: Fix undefined variables in Pages Router example.

Replace user.* with message.user.* to match NextAuth event signature.

       await dub.track.lead({
         clickId: dub_id,
         eventName: "Sign Up",
-        customerExternalId: user.id,
-        customerName: user.name,
-        customerEmail: user.email,
-        customerAvatar: user.image,
+        customerExternalId: message.user.id,
+        customerName: message.user.name,
+        customerEmail: message.user.email,
+        customerAvatar: message.user.image,
       });
conversions/leads/introduction.mdx (1)

99-107: Fix Go example: add missing imports and use exported CustomerExternalId

  • Add the missing "os" and "time" imports (os.Getenv is used by dub.WithSecurity; time.Unix is used when clearing the cookie).
  • Replace unexported customerExternalId with exported CustomerExternalId (Go struct fields must be exported).
    File: conversions/leads/introduction.mdx — imports block (lines 99–103), TrackLeadRequest block (lines 111–117), cookie deletion/time.Unix (~lines 118–121).
-import (
-    "context"
-    dub "github.com/dubinc/dub-go"
-    "net/http"
-)
+import (
+    "context"
+    "net/http"
+    "os"
+    "time"
+    dub "github.com/dubinc/dub-go"
+)

-    _, err = d.Track.Lead(context.Background(), &operations.TrackLeadRequest{
+    _, err = d.Track.Lead(context.Background(), &operations.TrackLeadRequest{
         ClickId:         dubId.Value,
         EventName:       "Sign Up",
-        customerExternalId:      customer.ID,
+        CustomerExternalId: customer.ID, // matches exported field used elsewhere in Go examples
         CustomerName:    customer.Name,
         CustomerEmail:   customer.Email,
         CustomerAvatar:  customer.Avatar,
     })
🧹 Nitpick comments (12)
snippets/conversion-tracking-prerequisites.mdx (2)

5-12: Avoid duplicated “Prerequisites” headings across pages.

Since the snippet includes “## Prerequisites”, any host page that also prints a “## Prerequisites” header will render duplicates. Either remove the header from the snippet or document that pages should not add their own header.

Apply one of these:

-## Prerequisites
+<!-- Heading intentionally omitted; host pages provide context -->

or standardize usage across pages to not add an extra “## Prerequisites” around this snippet.


9-9: Tighten copy.

“Then, you'd want to install …” → more direct: “Then install …”.

-Then, you'd want to install the `@dub/analytics` script to your website to track conversion events.
+Then install the `@dub/analytics` script on your website to track conversion events.
conversions/leads/segment.mdx (1)

110-112: cookies() is synchronous in App Router.

Remove await to avoid misleading example.

-const cookieStore = await cookies();
+const cookieStore = cookies();
conversions/leads/auth0.mdx (1)

30-64: TS types in a .js example; align filename or import.

Either make the example TypeScript (route.ts) or drop the type-only import in JS.

-```typescript app/api/auth/[auth0]/route.js
-import { handleAuth, handleCallback, type Session } from "@auth0/nextjs-auth0";
+```typescript app/api/auth/[auth0]/route.ts
+import { handleAuth, handleCallback, type Session } from "@auth0/nextjs-auth0";

Or, if keeping JS:

-```typescript app/api/auth/[auth0]/route.js
+```js app/api/auth/[auth0]/route.js
-import { handleAuth, handleCallback, type Session } from "@auth0/nextjs-auth0";
+import { handleAuth, handleCallback } from "@auth0/nextjs-auth0";
conversions/sales/google-tag-manager.mdx (2)

12-15: Grammar: singular agreement.

“Conversion tracking require” → “Conversion tracking requires”.

-  Conversion tracking require a [Business plan](https://dub.co/pricing)
+  Conversion tracking requires a [Business plan](https://dub.co/pricing)

77-77: Use raw file URLs for direct template downloads.

Leads GTM page uses raw.githubusercontent.com; align here for a one-click download.

-Download the [gtm-server-client-template/template.tpl](https://github.com/dubinc/gtm-server-client-template/blob/main/template.tpl) file and upload it to the Template Editor. You'll see a preview of the template:
+Download the [gtm-server-client-template/template.tpl](https://raw.githubusercontent.com/dubinc/gtm-server-client-template/main/template.tpl) file and upload it to the Template Editor. You'll see a preview of the template:
-Download the [gtm-server-tag-template/template.tpl](https://github.com/dubinc/gtm-server-tag-template/blob/main/template.tpl) file and upload it to the Template Editor. You'll see a preview of the template:
+Download the [gtm-server-tag-template/template.tpl](https://raw.githubusercontent.com/dubinc/gtm-server-tag-template/main/template.tpl) file and upload it to the Template Editor. You'll see a preview of the template:

Also applies to: 174-174

conversions/leads/clerk.mdx (4)

23-33: Use React-friendly iframe attribute casing.

CamelCase avoids JSX/TSX prop warnings.

-  frameborder="0"
+  frameBorder="0"
-  referrerpolicy="strict-origin-when-cross-origin"
+  referrerPolicy="strict-origin-when-cross-origin"
-  allowfullscreen
+  allowFullScreen

48-50: Fix token URL.

Use the canonical Dub dashboard tokens URL.

-    # get it here: https://d.to/tokens
+    # get it here: https://app.dub.co/settings/tokens

95-110: Commented fetch example: make callback async or drop await.

Minor consistency nit to prevent copy-paste errors.

-        }).then(res => {
+        }).then(async (res) => {
           if (res.ok) await user.reload();
           else console.error(res.statusText);
         });

161-163: cookies() is synchronous in Server Actions.

Remove await to match Next.js API.

-        const cookieStore = await cookies();
+        const cookieStore = cookies();
snippets/enable-conversion-tracking.mdx (2)

12-13: Duplicate sentence in Option 1.

Remove the repeated line.

Apply this diff:

-    To enable conversion tracking for all future links in a workspace, you can do the following:
-To enable conversion tracking for all future links in a workspace, you can do the following:
+    To enable conversion tracking for all future links in a workspace, you can do the following:

1-1: Microcopy tighten (optional).

Slightly crisper intro.

Apply this diff:

-First, you'll need to enable conversion tracking for your Dub links to be able to start tracking conversions.
+First, enable conversion tracking on your Dub links to start recording conversions.
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c91203d and c487ec6.

⛔ Files ignored due to path filters (1)
  • images/conversions/hubspot/installed-hubspot-integration.png is excluded by !**/*.png
📒 Files selected for processing (28)
  • conversions/leads/appwrite.mdx (1 hunks)
  • conversions/leads/auth0.mdx (1 hunks)
  • conversions/leads/better-auth.mdx (1 hunks)
  • conversions/leads/clerk.mdx (1 hunks)
  • conversions/leads/client-side.mdx (1 hunks)
  • conversions/leads/google-tag-manager.mdx (3 hunks)
  • conversions/leads/hubspot.mdx (1 hunks)
  • conversions/leads/introduction.mdx (2 hunks)
  • conversions/leads/next-auth.mdx (1 hunks)
  • conversions/leads/segment.mdx (1 hunks)
  • conversions/leads/supabase.mdx (1 hunks)
  • conversions/quickstart.mdx (1 hunks)
  • conversions/sales/client-side.mdx (1 hunks)
  • conversions/sales/google-tag-manager.mdx (2 hunks)
  • conversions/sales/introduction.mdx (1 hunks)
  • conversions/sales/segment.mdx (2 hunks)
  • conversions/sales/shopify.mdx (1 hunks)
  • conversions/sales/stripe.mdx (1 hunks)
  • partners/quickstart.mdx (1 hunks)
  • sdks/client-side/features/conversion-tracking.mdx (2 hunks)
  • sdks/client-side/installation-guides/shopify.mdx (2 hunks)
  • snippets/client-side-tracking-install.mdx (2 hunks)
  • snippets/conversion-tracking-prerequisites.mdx (1 hunks)
  • snippets/dub-client-install.mdx (2 hunks)
  • snippets/enable-conversion-tracking.mdx (1 hunks)
  • snippets/leads-intro.mdx (1 hunks)
  • snippets/leads-prerequisites.mdx (0 hunks)
  • snippets/sales-prerequisites.mdx (0 hunks)
💤 Files with no reviewable changes (2)
  • snippets/sales-prerequisites.mdx
  • snippets/leads-prerequisites.mdx
✅ Files skipped from review due to trivial changes (5)
  • conversions/sales/stripe.mdx
  • snippets/client-side-tracking-install.mdx
  • conversions/sales/client-side.mdx
  • sdks/client-side/installation-guides/shopify.mdx
  • conversions/sales/shopify.mdx
🚧 Files skipped from review as they are similar to previous changes (1)
  • conversions/leads/hubspot.mdx
🔇 Additional comments (24)
snippets/leads-intro.mdx (1)

9-9: Bullet update looks good.

“Booking a demo meeting” is a clearer lead example.

partners/quickstart.mdx (1)

81-81: Verify new docs path.

Confirm that /partners/embedded-referrals exists and is the intended destination for the “whitelabeled referral dashboard” link. If not, update to the correct route.

conversions/leads/client-side.mdx (2)

21-24: Quickstart section addition reads well.

Good placement after install steps; keeps the flow clear.


25-34: Helpful limitations warning.

Nice callout on client-side tracking caveats.

conversions/quickstart.mdx (1)

2-2: Title change: check nav and inbound links.

After renaming to “Conversion tracking”, verify docs.json/nav entries and any inbound links/redirects to the former “Quickstart” title still resolve correctly.

conversions/leads/appwrite.mdx (2)

9-9: Switched to shared prerequisites snippet.

Import path looks correct.

Ensure no extra “Prerequisites” header is present on this page to avoid duplication with the snippet’s own header.


17-17: Snippet usage LGTM.

Placement before provider‑specific steps is consistent with other guides.

conversions/sales/introduction.mdx (2)

9-9: Consolidated to ConversionTrackingPrerequisites.

Good move to centralize content.

Confirm there’s no local “Prerequisites” header around this snippet to prevent duplicate headings.


17-17: Usage placement is correct.

Reads naturally before “Configure sale tracking.”

conversions/leads/supabase.mdx (2)

9-9: Updated import to shared prerequisites.

Looks correct and aligns with the broader migration.

Check for any remaining references to LeadsPrerequisites in this repo to avoid drift.


17-17: Snippet placement LGTM.

Right before provider configuration; consistent across leads guides.

conversions/leads/google-tag-manager.mdx (2)

9-11: Switch to shared prerequisites snippet looks good.

Import + usage of ConversionTrackingPrerequisites is consistent with the new snippet approach.

Please confirm the snippet exports a default component and that the docs build resolves “/snippets/conversion-tracking-prerequisites.mdx”.

Also applies to: 17-17


55-55: No-op content change.

Whitespace-only change; nothing to review.

Also applies to: 142-142

conversions/leads/better-auth.mdx (1)

10-10: Prerequisites snippet migration LGTM.

Import path and component usage match the new shared snippet.

Ensure the page order still renders as intended after inserting the shared prerequisites section.

Also applies to: 18-18

conversions/leads/next-auth.mdx (2)

9-9: Prerequisites snippet migration LGTM.

Consistent with other guides adopting the shared prerequisites.

Also applies to: 17-17


34-67: Cookie deletion semantics caution.

Deleting cookies via cookies() works in Route Handlers/Server Actions, but within NextAuth event context it may not persist. Consider deleting in the response (e.g., via a follow-up Route Handler/API route) after successful lead tracking.

Also applies to: 69-98

conversions/leads/segment.mdx (1)

9-9: Prerequisites snippet migration LGTM.

Matches the standardized pattern.

Also applies to: 17-17

conversions/leads/auth0.mdx (1)

9-9: Prerequisites snippet migration LGTM.

Import and usage look correct.

Also applies to: 17-17

conversions/sales/google-tag-manager.mdx (1)

8-8: Prerequisites snippet migration LGTM.

Consistent with the leads guides.

Also applies to: 24-24

sdks/client-side/features/conversion-tracking.mdx (1)

7-7: Quickstart insertion LGTM.

EnableConversionTracking import and placement before install section reads well.

Confirm the horizontal rule (“---”) renders as intended in your MDX theme.

Also applies to: 44-49

conversions/leads/clerk.mdx (1)

9-9: Prerequisites snippet migration LGTM.

Import and usage are consistent with other guides.

Also applies to: 17-17

conversions/sales/segment.mdx (1)

8-8: Good consolidation to shared prerequisites; confirm build and heading nesting.

  • Path and export look right; verify the snippet exists and doesn’t duplicate an H2 already on this page.
  • After switching to the shared snippet, double-check any references like “first two steps” still make sense.

Also applies to: 17-17

conversions/leads/introduction.mdx (1)

9-9: Consistent prerequisites across leads pages—nice.

Looks correct; please confirm the shared snippet’s copy is lead‑appropriate (no sales‑only phrasing) and that TOC anchors remain stable.

Also applies to: 18-18

snippets/dub-client-install.mdx (1)

8-9: Card props change to self‑closing horizontal variants—verify component API and a11y.

  • Ensure Card supports the horizontal prop without children.
  • Confirm accessible names remain (title as aria-label) and no SEO content was lost with removal of descriptions.

Also applies to: 14-15, 33-34, 39-40, 45-46, 51-52, 53-58

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🧹 Nitpick comments (9)
snippets/leads-attributes.mdx (5)

6-6: Verify cross-reference and tighten phrasing

  • Confirm the parameter name and path: “leadEventName prop in /track/sale”. If there’s a canonical doc for sale tracking, link it.
  • Slightly clearer wording.
-| `eventName`          | **Yes**  | The name of the lead event to track. Can also be used as a unique identifier to associate a given lead event for a customer for a subsequent sale event (via the `leadEventName` prop in `/track/sale`).                                                                                                                                                                          |
+| `eventName`          | **Yes**  | The name of the lead event to track. Can also serve as a unique identifier to tie this lead to a subsequent sale event (via the `leadEventName` parameter on `/track/sale`). |

7-7: Call out uniqueness scope for customerExternalId

Readers need to know if this must be unique per workspace/account and if it’s immutable.

-| `customerExternalId` | **Yes**  | The unique ID of the customer in your system. Will be used to identify and attribute all future events to this customer.                                                                                                                                                                                                                                                          |
+| `customerExternalId` | **Yes**  | The unique ID of the customer in your system (must be unique per workspace). Used to identify and attribute all future events to this customer. |

8-10: Small wording nits and optional guardrails for PII/URLs

  • Prefer “If omitted” to “If not passed.”
  • Consider noting expected formats/normalization (e.g., lowercasing emails, HTTPS-only avatar URLs), if enforced.
-| `customerName`       | No       | The name of the customer. If not passed, a random name will be generated (e.g. "Big Red Caribou").                                                                                                                                                                                                                                                                                |
+| `customerName`       | No       | The name of the customer. If omitted, a random name will be generated (e.g., "Big Red Caribou"). |

For customerEmail and customerAvatar, add format expectations only if they’re validated at the API boundary.


12-12: Clarify metadata type and limits

Specify the accepted shape (e.g., JSON object), size enforcement (stringified length vs. total of values), and truncation/error behavior.

Example edit (adjust if inaccurate):

-| `metadata`           | No       | Additional metadata to be stored with the lead event. Max 10,000 characters.                                                                                                                                                                                                                                                                                                      |
+| `metadata`           | No       | Additional JSON metadata to store with the lead event (object). Limit: 10,000 characters when stringified. Payloads exceeding the limit are rejected or truncated (confirm behavior). |

5-5: Clarify “Required” vs deferred behavior; tighten grammar

File: snippets/leads-attributes.mdx Lines: 5-5

Make explicit that clickId is required except when tracking deferred lead events; fix two small grammar issues.

-| `clickId`            | **Yes**  | The unique ID of the click that the lead conversion event is attributed to. You can read this value from `dub_id` cookie. If an empty string is provided (i.e. if you're using [tracking a deferred lead event](/conversions/leads/deferred)), Dub will try to find an existing customer with the provided `customerExternalId` and use the `clickId` from the customer if found. |
+| `clickId`            | **Yes*** | The unique ID of the click that the lead conversion event is attributed to. You can read this value from the `dub_id` cookie. When [tracking a deferred lead event](/conversions/leads/deferred), you may pass an empty string; Dub will try to find an existing customer with the provided `customerExternalId` and reuse that customer’s `clickId` if found. |

If you leave “Yes” unchanged, add a short footnote below the table explaining the deferred-case exception.

conversions/leads/deferred.mdx (4)

14-14: Grammar nit: “times when”, not “times where”.

Replace “there are times where” with “there are times when” for correctness.

-However, there are times where signups alone might not be the clearest indicator of a lead conversion event.
+However, there are times when signups alone might not be the clearest indicator of a lead conversion event.

40-41: Call out SDK-specific casing differences.

Parameter casing differs across SDKs (e.g., customerExternalId vs external_id). Add a one‑line note before the examples to reduce copy/paste errors.

 To do this, you'll need to set the `mode` property to `deferred` when tracking the lead event. With this, Dub will still track the customer and the click ID they came from, but defer the actual lead event creation to a subsequent request.
+Note: SDKs use language‑idiomatic casing (e.g., JavaScript: `customerExternalId`; Python/Ruby: `external_id`). Use the field names shown in the snippet for your language.

49-65: Framework-specific cookie API; clarify context or show two variants.

req.cookies[...] / res.cookies.set(...) is not Express‑standard (Express uses req.cookies/res.cookie). Either clarify this is Next.js App Router or show both variants.

-const dubId = req.cookies["dub_id"];
-// ...
-res.cookies.set("dub_id", "", {
+// Next.js App Router:
+const dubId = req.cookies?.get?.("dub_id")?.value;
+// ...
+res.cookies.set("dub_id", "", {
   expires: new Date(0),
 });
+// Express:
+// const dubId = req.cookies?.dub_id;
+// res.cookie("dub_id", "", { expires: new Date(0) });

121-129: Ruby: namespace/gem mismatch.

require 'dub' but instantiates ::OpenApiSDK::Dub. Confirm the correct gem and namespace. If the gem exposes Dub, avoid the OpenApiSDK namespace; otherwise, require the appropriate gem.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c487ec6 and c8deeb0.

📒 Files selected for processing (6)
  • conversions/leads/deferred.mdx (1 hunks)
  • conversions/leads/hubspot.mdx (1 hunks)
  • conversions/leads/introduction.mdx (3 hunks)
  • docs.json (1 hunks)
  • snippets/enable-conversion-tracking.mdx (1 hunks)
  • snippets/leads-attributes.mdx (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
  • conversions/leads/hubspot.mdx
  • docs.json
  • conversions/leads/introduction.mdx
  • snippets/enable-conversion-tracking.mdx
🔇 Additional comments (2)
snippets/leads-attributes.mdx (2)

3-4: Table structure LGTM

Header and alignment look consistent with the rest of the docs.


11-11: Document default mode and clarify clickId relationship

File: snippets/leads-attributes.mdx Lines: 11-11

-| `mode`               | No       | The mode to use for tracking the lead event. `async` will not block the request; `wait` will block the request until the lead event is fully recorded in Dub; `deferred` will defer the lead event creation to a subsequent request.                                                                                                                                              |
+| `mode`               | No       | The mode to use for tracking the lead event. Default: `async`. `async` does not block the request; `wait` blocks until the lead is fully recorded in Dub; `deferred` defers lead creation to a subsequent request (often used with `clickId=""`). |

Consider documenting timeout/latency expectations for wait.

Comment on lines +73 to +86
dub_id = request.cookies.get('dub_id')
if dub_id:
dub.track.lead({
'click_id': dub_id,
'mode': 'deferred',
'event_name': 'Sign Up',
'external_id': customer.id,
'customer_name': customer.name,
'customer_email': customer.email,
'customer_avatar': customer.avatar
})
# delete the dub_id cookie
response.delete_cookie('dub_id')
```
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Python: undefined response and framework ambiguity.

response.delete_cookie('dub_id') references an undefined variable. Provide a concrete example (e.g., Flask) or remove the line and add a comment to delete the cookie using the framework’s response object.

-dub.track.lead({
+res = dub.track.lead({
     'click_id': dub_id,
     'mode': 'deferred',
     'event_name': 'Sign Up',
     'external_id': customer.id,
     'customer_name': customer.name,
     'customer_email': customer.email,
     'customer_avatar': customer.avatar
 })
-# delete the dub_id cookie
-response.delete_cookie('dub_id')
+# delete the dub_id cookie using your framework's response:
+# Flask example:
+# from flask import make_response
+# resp = make_response(...)
+# resp.delete_cookie('dub_id')
🤖 Prompt for AI Agents
In conversions/leads/deferred.mdx around lines 73 to 86, the code calls
response.delete_cookie('dub_id') but response is undefined and the framework is
ambiguous; fix by using a concrete framework pattern (for example, in Flask
create/use the response object returned by make_response or the view return and
call response.delete_cookie('dub_id') before returning) or remove that line and
replace it with a short comment telling the caller to delete the 'dub_id' cookie
using the framework's response object.

Comment on lines +91 to +119
import (
"context"
dub "github.com/dubinc/dub-go"
"net/http"
)

d := dub.New(
dub.WithSecurity(os.Getenv("DUB_API_KEY")),
)

dubId, err := r.Cookie("dub_id")
if err == nil {
_, err = d.Track.Lead(context.Background(), &operations.TrackLeadRequest{
ClickId: dubId.Value,
Mode: "deferred",
EventName: "Sign Up",
customerExternalId: customer.ID,
CustomerName: customer.Name,
CustomerEmail: customer.Email,
CustomerAvatar: customer.Avatar,
})
// delete the dub_id cookie
http.SetCookie(w, &http.Cookie{
Name: "dub_id",
Value: "",
Expires: time.Unix(0, 0),
})
}
```
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

❓ Verification inconclusive

Go: missing imports, undefined operations, and likely wrong struct field casing.

  • Missing imports: os, time, and models/operations.
  • operations package is used but not imported.
  • Field customerExternalId is unexported; Go structs typically export as CustomerExternalID (verify actual SDK).
  • Uses r/w without showing handler context; add a brief comment.
-import (
-    "context"
-    dub "github.com/dubinc/dub-go"
-    "net/http"
-)
+import (
+    "context"
+    "net/http"
+    "os"
+    "time"
+    dub "github.com/dubinc/dub-go"
+    "github.com/dubinc/dub-go/models/operations"
+)
@@
-    _, err = d.Track.Lead(context.Background(), &operations.TrackLeadRequest{
+    _, err = d.Track.Lead(context.Background(), &operations.TrackLeadRequest{
         ClickId:         dubId.Value,
         Mode:            "deferred",
         EventName:       "Sign Up",
-        customerExternalId:      customer.ID,
-        CustomerName:    customer.Name,
-        CustomerEmail:   customer.Email,
-        CustomerAvatar:  customer.Avatar,
+        // Verify exact field name in the SDK:
+        // CustomerExternalID: customer.ID,
+        CustomerName:     customer.Name,
+        CustomerEmail:    customer.Email,
+        CustomerAvatar:   customer.Avatar,
     })
@@
-    http.SetCookie(w, &http.Cookie{
+    // In an http.HandlerFunc(w http.ResponseWriter, r *http.Request):
+    http.SetCookie(w, &http.Cookie{
         Name:    "dub_id",
         Value:   "",
         Expires: time.Unix(0, 0),
     })

To confirm field names and package paths, please verify against the current dub-go SDK docs.


Go: missing imports, wrong SDK type, and unexported field usage

  • Add imports: os, time, and the operations package (github.com/dubinc/dub-go/models/operations). (github.com)
  • Use the SDK request body type: replace operations.TrackLeadRequest with operations.TrackLeadRequestBody (Track.Lead expects *operations.TrackLeadRequestBody). (pkg.go.dev)
  • Replace the unexported JSON-style field (customerExternalId) with the SDK's exported field(s) — e.g., ClickID and the SDK's exported external-ID field (CustomerExternalID / ExternalID). Verify the exact field name in the SDK before committing. (dub.co)
  • Ensure the snippet is inside an http.Handler (w http.ResponseWriter, r *http.Request) since r/w are used but not shown.
🤖 Prompt for AI Agents
In conversions/leads/deferred.mdx around lines 91-119, the snippet is missing
imports, using the wrong SDK request type, and referencing an unexported field;
add imports for os and time and the operations package
(github.com/dubinc/dub-go/models/operations), change operations.TrackLeadRequest
to the SDK request body type operations.TrackLeadRequestBody (Track.Lead expects
*operations.TrackLeadRequestBody), replace the unexported customerExternalId
field with the SDK's exported external ID field (confirm and use the exact
exported name such as CustomerExternalID or ExternalID), and ensure this code is
placed inside an http.Handler function signature (w http.ResponseWriter, r
*http.Request) so r and w are defined before committing.

Comment on lines +164 to +167
$request->customerExternalId = $customer->id;
$request->customerNasme = $customer->name;
$request->customerEmail = $customer->email;
$request->customerAvatar = $customer->avatar;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

PHP: typo customerNasmecustomerName.

This will silently drop the name in most SDKs. Fix the property.

-    $request->customerNasme = $customer->name;
+    $request->customerName = $customer->name;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
$request->customerExternalId = $customer->id;
$request->customerNasme = $customer->name;
$request->customerEmail = $customer->email;
$request->customerAvatar = $customer->avatar;
$request->customerExternalId = $customer->id;
$request->customerName = $customer->name;
$request->customerEmail = $customer->email;
$request->customerAvatar = $customer->avatar;
🤖 Prompt for AI Agents
In conversions/leads/deferred.mdx around lines 164 to 167, there's a typo
setting $request->customerNasme which will drop the name; change that property
to $request->customerName to match the intended field and the surrounding
properties so the customer's name is correctly passed.

Comment on lines +223 to +235
d := dub.New(
dub.WithSecurity(os.Getenv("DUB_API_KEY")),
)

d.Track.Lead(context.Background(), &operations.TrackLeadRequest{
ClickId: "",
EventName: "Sign Up",
customerExternalId: customer.ID,
CustomerName: customer.Name,
CustomerEmail: customer.Email,
CustomerAvatar: customer.Avatar,
})
```
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

❓ Verification inconclusive

Go (Step 2): same issues as Step 1.

Add missing imports for os (used above if applicable) and operations, and verify struct field casing for customer external ID.

-import (
-    "context"
-    dub "github.com/dubinc/dub-go"
-    "net/http"
-)
+import (
+    "context"
+    dub "github.com/dubinc/dub-go"
+    "github.com/dubinc/dub-go/models/operations"
+)
@@
-d.Track.Lead(context.Background(), &operations.TrackLeadRequest{
+d.Track.Lead(context.Background(), &operations.TrackLeadRequest{
     ClickId:         "",
     EventName:       "Sign Up",
-    customerExternalId:      customer.ID,
+    // CustomerExternalID: customer.ID, // verify exact name in SDK
     CustomerName:    customer.Name,
     CustomerEmail:   customer.Email,
     CustomerAvatar:  customer.Avatar,
 })

Go (Step 2): add imports and fix Track.Lead example

  • File: conversions/leads/deferred.mdx (lines 223–235) — add missing imports and correct the Go SDK types/fields.
  • Imports: add "os" and "github.com/dubinc/dub-go/models/operations".
  • Replace the example payload with the SDK request type and exported fields (use TrackLeadRequestBody and PascalCase fields):
    • Use &operations.TrackLeadRequestBody{ ClickID: "", EventName: "Sign Up", CustomerExternalID: customer.ID, CustomerName: customer.Name, CustomerEmail: customer.Email, CustomerAvatar: customer.Avatar }.
🤖 Prompt for AI Agents
In conversions/leads/deferred.mdx around lines 223 to 235, the Go example is
missing imports and uses incorrect SDK types/field names; add imports "os" and
"github.com/dubinc/dub-go/models/operations" at the top of the snippet, replace
the payload with the correct SDK request type and exported PascalCase fields by
using &operations.TrackLeadRequestBody{ ClickID: "", EventName: "Sign Up",
CustomerExternalID: customer.ID, CustomerName: customer.Name, CustomerEmail:
customer.Email, CustomerAvatar: customer.Avatar }, and ensure the dub.New call
uses dub.WithSecurity(os.Getenv("DUB_API_KEY")) as shown.

Comment on lines +271 to +274
$request->customerExternalId = $customer->id;
$request->customerNasme = $customer->name;
$request->customerEmail = $customer->email;
$request->customerAvatar = $customer->avatar;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

PHP: repeated typo customerNasmecustomerName.

Fix in Step 2 as well.

-$request->customerNasme = $customer->name;
+$request->customerName = $customer->name;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
$request->customerExternalId = $customer->id;
$request->customerNasme = $customer->name;
$request->customerEmail = $customer->email;
$request->customerAvatar = $customer->avatar;
$request->customerExternalId = $customer->id;
$request->customerName = $customer->name;
$request->customerEmail = $customer->email;
$request->customerAvatar = $customer->avatar;
🤖 Prompt for AI Agents
In conversions/leads/deferred.mdx around lines 271 to 274, there's a typo
assigning $request->customerNasme; change it to $request->customerName, and
similarly update the same typo occurrence in Step 2 of the document; ensure both
assignments use customerName exactly and leave the other properties
(customerExternalId, customerEmail, customerAvatar) unchanged.

@steven-tey steven-tey merged commit 76d6405 into main Sep 22, 2025
1 check passed
@steven-tey steven-tey deleted the hubspot branch September 22, 2025 22:45
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (3)
conversions/quickstart.mdx (3)

15-16: Grammar: subject–verb agreement.

“Conversion tracking require” → “Conversion tracking requires”.

Apply this diff:

-  Conversion tracking require a [Business plan](https://dub.co/pricing)
+  Conversion tracking requires a [Business plan](https://dub.co/pricing)

38-38: Grammar: tense consistency.

“detects … and storing” → “detects … and stores”.

Apply this diff:

-This script detects the `dub_id` query parameter and storing it as a first-party cookie, which will be used to attribute subsequent conversion events to the original link.
+This script detects the `dub_id` query parameter and stores it as a first-party cookie, which will be used to attribute subsequent conversion events to the original link.

22-26: Optional: improve image alt text for accessibility/SEO.

Consider a more descriptive alt, e.g., “Screenshot of Dub conversion analytics dashboard” rather than “Conversion analytics”.

Apply this diff:

-    alt="Conversion analytics"
+    alt="Screenshot of the Dub conversion analytics dashboard"
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c8deeb0 and cc60cd0.

📒 Files selected for processing (1)
  • conversions/quickstart.mdx (1 hunks)
🔇 Additional comments (2)
conversions/quickstart.mdx (2)

28-28: LGTM on intro sentence.

Clear and sets context well.


7-12: Snippet imports resolve — no action required.

All referenced /snippets/*.mdx files exist under ./snippets and contain MDX/JSX content; the imports in conversions/quickstart.mdx match those files.

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.

2 participants