-
Notifications
You must be signed in to change notification settings - Fork 38
Dub iOS SDK docs #232
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Dub iOS SDK docs #232
Conversation
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 26 minutes and 22 seconds before requesting another review. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the 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. 📒 Files selected for processing (8)
WalkthroughAdds mobile (iOS/Swift) SDK docs and snippets, introduces publishable keys docs, renames lead attributes snippet, refactors client-side tracking install steps into components, updates deep-link flows and SDK examples, and alters navigation and multiple internal links and anchors. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor User as User
participant App as iOS App (SwiftUI/UIKit)
participant SDK as Dub iOS SDK
participant API as Dub API
participant Conv as Conversions
rect rgba(230,245,255,0.6)
note over User,App: Deep link open / deferred install flow
User->>App: Open deep link URL
App->>SDK: Dub.setup(publishableKey, domain) [init]
App->>SDK: trackOpen(deepLink? / dubDomain?) async
SDK->>API: POST /track/open (deepLink or dubDomain)
API-->>SDK: { destinationUrl, clickId?, firstLaunch? }
SDK-->>App: Response (destinationUrl / clickId)
App->>App: Navigate to destinationUrl
end
rect rgba(240,255,230,0.6)
note over App,Conv: Conversion tracking
App->>SDK: trackLead(params, clickId?)
SDK->>API: POST /track/lead
API->>Conv: Record lead
Conv-->>SDK: Ack
SDK-->>App: Success/Error
App->>SDK: trackSale(params, clickId?)
SDK->>API: POST /track/sale
API->>Conv: Record sale
Conv-->>SDK: Ack
SDK-->>App: Success/Error
end
note over API: Probabilistic fallback used when clipboard paste permission declined or clipboard unavailable
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Poem
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
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. Comment |
8ee7127
to
2cff6c0
Compare
There was a problem hiding this 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 (23)
conversions/leads/client-side.mdx (2)
2-2
: Title clarification LGTM; consider aligning OG title.Adding “(web)” improves clarity. Optionally mirror it in og:title for consistency.
-og:title: Client-side lead tracking with Dub +og:title: Client-side lead tracking (web) with Dub
32-34
: Possible broken link: stray /docs prefix.Other internal links omit “/docs”. This likely 404s.
-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)Please confirm the correct base path in the preview build.
conversions/sales/client-side.mdx (2)
2-2
: Title clarification LGTM; consider aligning OG title.Match og:title to include “(web)”.
-og:title: Client-side sale tracking with Dub +og:title: Client-side sale tracking (web) with Dub
34-34
: Possible broken link: stray /docs prefix.Keep internal paths consistent with others in this doc.
-For more accurate conversion tracking, consider using [server-side conversion tracking](/docs/conversions/sales/introduction) +For more accurate conversion tracking, consider using [server-side conversion tracking](/conversions/sales/introduction)Please verify in the deploy preview.
integrations/quickstart.mdx (2)
4-4
: Nit: stray period after “OAuth 2.0”.Minor grammar polish.
-description: "Learn how to authenticate users with OAuth 2.0. for your Dub integration." +description: "Learn how to authenticate users with OAuth 2.0 for your Dub integration."
21-21
: Nit: article before “OAuth”.Use “an OAuth”.
-We recommend you use a OAuth client library to integrate the OAuth flow. +We recommend you use an OAuth client library to integrate the OAuth flow.snippets/steps/initialize-ios-sdk.mdx (1)
12-13
: Consider using environment variables in documentation!The placeholder keys
<DUB_PUBLISHABLE_KEY>
and<DUB_DOMAIN>
are clear, but consider mentioning environment variable usage or configuration best practices for production apps.Consider adding a brief note about using environment variables or configuration files for these values:
// Step 1: Obtain your Dub domain and publishable key - private let dubPublishableKey = "<DUB_PUBLISHABLE_KEY>" - private let dubDomain = "<DUB_DOMAIN>" + // For production, consider using environment variables or a configuration file + private let dubPublishableKey = "<DUB_PUBLISHABLE_KEY>" // e.g., ProcessInfo.processInfo.environment["DUB_PUBLISHABLE_KEY"] + private let dubDomain = "<DUB_DOMAIN>" // e.g., "your-domain.link"snippets/dub-client-mobile-install.mdx (1)
69-69
: Consider adding persistence explanation for first launch tracking!The
@AppStorage("is_first_launch")
approach is good, but consider adding a brief comment explaining why first launch tracking is important for deferred deep linking.Add a clarifying comment:
- @AppStorage("is_first_launch") private var isFirstLaunch = true + // Track first launch for deferred deep linking attribution + @AppStorage("is_first_launch") private var isFirstLaunch = trueconcepts/deep-links/attribution.mdx (5)
4-4
: Fix grammar in description.Use “conversion events” (singular “conversion” as adjective).
-description: "Learn how to use deep link attribution to track conversions events with Dub." +description: "Learn how to use deep link attribution to track conversion events with Dub."
7-10
: Remove unused import.InstallationGuides is imported but never used.
-import InstallationGuides from "/snippets/dub-client-mobile-installation-guides.mdx"; import InstallIosSdkStep from "/snippets/steps/install-ios-sdk.mdx"; import InitializeIosSdkStep from "/snippets/steps/initialize-ios-sdk.mdx"; import ViewConversions from "/snippets/view-conversions.mdx";
74-119
: Avoid double “open” tracking on cold-start from a deep link.onAppear (first launch) and onOpenURL can both fire on cold-start, producing two trackOpen calls. Gate first-launch tracking if a deep link was used.
- .onOpenURL { url in - trackOpen(deepLink: url) - } + .onOpenURL { url in + isFirstLaunch = false + trackOpen(deepLink: url) + } .onAppear { if isFirstLaunch { trackOpen() isFirstLaunch = false } }
107-115
: Show a concrete navigation example.A brief example improves copy-pasteability.
- // Navigate to the destination URL + // Navigate to the destination URL + if let url = URL(string: url) { + UIApplication.shared.open(url) + }
164-176
: Clarify amount units and currency casing.Specify whether amount is in cents (Int) and whether currency expects ISO 4217 uppercase (e.g., “USD”).
- amount: Int, - currency: String = "usd", + amount: Int, // e.g., amount in cents + currency: String = "USD",snippets/dub-client-mobile-installation-guides.mdx (1)
3-9
: Consider clarifying the card title.“iOS (Swift)” is clearer than “Swift” in an installation context.
- <Card - title="Swift" + <Card + title="iOS (Swift)" icon="swift" href="/sdks/client-side-mobile/installation-guides/swift" >api-reference/introduction.mdx (1)
22-23
: Unify placeholder token formatting across examples.Use a consistent style (either dub_xxxxxx or ) in all samples.
-Authorization: Bearer dub_xxxxxx +Authorization: Bearer <token> @@ - --header 'Authorization: Bearer <token>' + --header 'Authorization: Bearer <token>'Also applies to: 236-237
sdks/overview.mdx (1)
36-43
: Align card title with product naming.Use “Dub iOS SDK” for consistency with other cards.
- <Card title="dub-ios" icon="swift" href="/sdks/client-side-mobile/introduction"> - Dub iOS SDK + <Card title="Dub iOS SDK" icon="swift" href="/sdks/client-side-mobile/introduction"> + Dub iOS SDK </Card>snippets/steps/allowlist-domains.mdx (2)
11-13
: Update alt text to describe the image content.Alt should mention “Allowed hostnames” for accuracy/accessibility.
- alt="Enabling conversion tracking for a workspace" + alt="Configuring Allowed Hostnames for conversion tracking"
16-20
: Standardize terminology: “allowlist” vs “allow list”.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: @@ -- `*.example.com`: Tracks traffic from **all subdomains** of `example.com`, but **not** from `example.com` itself. +- `*.example.com`: Tracks traffic from **all subdomains** of `example.com`, but **not** from `example.com` itself.sdks/client-side-mobile/introduction.mdx (2)
3-3
: Fix typo in description.Remove duplicate “the”.
-description: Learn more about the the Dub client-side mobile SDKs. +description: Learn more about the Dub client-side mobile SDKs.
6-8
: Remove unused import.DubAnalyticsParams is not used in this page.
-import DubAnalyticsParams from "/snippets/dub-analytics-params.mdx";
api-reference/publishable-keys.mdx (1)
24-32
: Add revocation/rotation note.Briefly mention that publishable keys are per-workspace, can be revoked/rotated, and that unused keys should be removed.
<Steps> <GeneratePublishableKeyStep /> <AllowlistDomainsStep /> <Step title="Use your publishable key"> -You can now use your publishable key to authenticate client-side requests in your application. Usage will depend on the client-side SDK you are using. +You can now use your publishable key to authenticate client-side requests in your application. Usage will depend on the client-side SDK you are using. + +Tip: Publishable keys are scoped to a workspace and can be revoked or rotated at any time. Remove unused keys for better hygiene. </Step> </Steps>sdks/client-side-mobile/installation-guides/swift.mdx (2)
6-9
: Remove unused imports (and react-specific snippet).These aren’t referenced on the page.
-import DubAnalyticsParams from "/snippets/dub-analytics-params-react.mdx"; -import DubClientInstallVerify from "/snippets/dub-client-install-verify.mdx";
14-16
: Clarify domain requirement phrasing.Readers may think DUB_DOMAIN is an env var. Prefer plain guidance about the domain value and link to the allowlist step.
-1. Obtain your [publishable key](/api-reference/publishable-keys) (`DUB_PUBLISHABLE_KEY`) from your [workspace's Analytics settings page](https://app.dub.co/settings/analytics) and allowlist your site's domain (`DUB_DOMAIN`) to allow the client-side conversion events to be ingested by Dub. +1. Obtain your [publishable key](/api-reference/publishable-keys) from your [workspace's Analytics settings page](https://app.dub.co/settings/analytics), and [allowlist your site’s domain](/api-reference/publishable-keys#create-a-publishable-key) so client-side conversion events can be ingested by Dub.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (27)
api-reference/introduction.mdx
(2 hunks)api-reference/publishable-keys.mdx
(1 hunks)concepts/deep-links/attribution.mdx
(1 hunks)concepts/deep-links/deferred-deep-linking.mdx
(5 hunks)concepts/deep-links/quickstart.mdx
(5 hunks)conversions/leads/client-side.mdx
(1 hunks)conversions/leads/google-tag-manager.mdx
(1 hunks)conversions/quickstart.mdx
(2 hunks)conversions/sales/client-side.mdx
(1 hunks)conversions/sales/google-tag-manager.mdx
(2 hunks)conversions/sales/shopify.mdx
(1 hunks)data-model.mdx
(1 hunks)docs.json
(8 hunks)integrations/quickstart.mdx
(1 hunks)sdks/client-side-mobile/installation-guides/swift.mdx
(1 hunks)sdks/client-side-mobile/introduction.mdx
(1 hunks)sdks/client-side/introduction.mdx
(1 hunks)sdks/overview.mdx
(1 hunks)snippets/client-side-tracking-install.mdx
(1 hunks)snippets/dub-client-mobile-install.mdx
(1 hunks)snippets/dub-client-mobile-installation-guides.mdx
(1 hunks)snippets/leads-intro.mdx
(1 hunks)snippets/sales-intro.mdx
(1 hunks)snippets/steps/allowlist-domains.mdx
(1 hunks)snippets/steps/generate-publishable-key.mdx
(1 hunks)snippets/steps/initialize-ios-sdk.mdx
(1 hunks)snippets/steps/install-ios-sdk.mdx
(1 hunks)
🔇 Additional comments (49)
sdks/client-side/introduction.mdx (1)
44-44
: Typo fix looks good."referece" → "reference" is correct.
snippets/sales-intro.mdx (1)
2-3
: Grammar fix LGTM.“requires” is correct.
integrations/quickstart.mdx (1)
240-240
: API Keys link update LGTM.Target now matches the new docs location.
conversions/sales/google-tag-manager.mdx (3)
12-14
: Grammar fix LGTM.“requires” is correct.
219-219
: API Keys link update LGTM.Matches the new API Keys page.
81-89
: Use raw GitHub URLs for template downloads (import will fail otherwise)GTM’s Import requires the raw .tpl file, not the GitHub HTML page.
File: conversions/sales/google-tag-manager.mdx — Lines: 81-89 (also applies to 178-186)
-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. +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.-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. +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.Test the Import flow with these raw links.
snippets/leads-intro.mdx (1)
2-3
: Grammar fix LGTM.“requires” is correct.
conversions/leads/google-tag-manager.mdx (1)
184-184
: API Keys link update LGTM.Aligned with the new API Keys docs.
conversions/sales/shopify.mdx (1)
10-10
: LGTM!Grammar correction properly fixes the verb agreement to match the plural subject "Conversion tracking."
data-model.mdx (1)
17-17
: LGTM!The link update from
/api-reference/tokens
to/api-reference/api-keys
aligns with the broader documentation restructuring in this PR to consolidate API key documentation.snippets/steps/install-ios-sdk.mdx (1)
1-16
: Excellent modular installation guide!This step provides clear, comprehensive installation instructions with proper prerequisites and follows the established snippet pattern for reusability across the documentation.
snippets/steps/generate-publishable-key.mdx (1)
1-14
: Clean modular approach for publishable key generation!This follows the established pattern of reusable step components and provides clear guidance with visual support for the key generation process.
concepts/deep-links/deferred-deep-linking.mdx (4)
472-472
: Good clarification on tracking methods!The update to mention both direct API calls and supported Dub Mobile SDKs provides users with multiple implementation options for the
/track/open
endpoint.
482-482
: Comprehensive coverage of IP-based tracking scenarios!The addition of "or the user declined paste permissions" properly documents all scenarios where IP-based tracking would be used instead of clipboard-based tracking.
491-491
: Accurate conditional logic documentation!The clarification that IP-based tracking is used when "no deep link is found in the clipboard or the user declined paste permissions" correctly reflects the decision logic.
558-558
: Excellent SwiftUI labeling consistency!The specific "iOS (SwiftUI)" labels help users quickly identify the appropriate code samples for their development environment, distinguishing from UIKit implementations.
Also applies to: 680-680
conversions/quickstart.mdx (2)
15-15
: LGTM!Grammar correction properly fixes the verb agreement to match the plural subject "Conversion tracking."
31-33
: Verify anchor encoding consistency across documentation!The anchor updates use URL encoding (e.g.,
%3A
for:
,%2B
for+
) which suggests a systematic change. Ensure this encoding pattern is applied consistently across all internal documentation links.Run the following script to check for consistency in anchor encoding patterns:
snippets/steps/initialize-ios-sdk.mdx (1)
1-29
: Comprehensive initialization guide!The step-by-step approach with clear comments and SwiftUI environment integration provides excellent guidance for developers implementing the Dub iOS SDK.
snippets/dub-client-mobile-install.mdx (3)
88-103
: Robust async error handling implementation!The
trackOpen
implementation properly handles both URL parsing and async operations with appropriate error handling usingDubError
.
169-203
: Comprehensive sale tracking parameters!The
trackSale
function signature covers all the necessary parameters with sensible defaults, providing flexibility for different use cases while maintaining simplicity for basic usage.
1-211
: Excellent comprehensive mobile installation guide!This snippet provides a complete end-to-end implementation guide covering installation, initialization, deep link tracking, and optional conversion events. The SwiftUI examples are well-structured and production-ready.
api-reference/introduction.mdx (1)
19-19
: LGTM: link to API key doc.Nice upgrade from plain text to a direct link.
Please confirm /api-reference/api-keys exists in this PR’s navigation.
api-reference/publishable-keys.mdx (1)
12-18
: LGTM: clear positioning and format.Good distinction from API keys and example env var.
concepts/deep-links/attribution.mdx (2)
41-45
: Verify percent-encoded anchors resolve.These in-page fragment links contain encoded characters; confirm the docs site generates identical slugs for the target headings.
204-208
: Confirm endpoint doc slugs.Ensure these endpoint pages exist and match current slugs.
sdks/client-side-mobile/installation-guides/swift.mdx (1)
22-23
: Confirm that renders init + usage.If it doesn't include initialization + first-run verification, consider embedding the init step or a verify snippet here.
snippets/client-side-tracking-install.mdx (6)
1-2
: LGTM! Good modularization of components.The imports of modular components (
GeneratePublishableKeyStep
andAllowlistDomainsStep
) follow a consistent pattern and improve maintainability by extracting reusable steps.
8-8
: LGTM! Clean component usage.The
GeneratePublishableKeyStep
component usage is clean and follows the established pattern.
10-10
: LGTM! Consistent component usage.The
AllowlistDomainsStep
component usage maintains consistency with the other modular components.
16-18
: LGTM! Good use of nested component imports.The inline import and usage of
DubClientInstall
component within the step is a clean approach that keeps the related functionality together.
20-21
: LGTM! Clear guidance on publishable key configuration.The text clearly emphasizes the importance of configuring the publishable key, which is crucial for proper functionality.
22-54
: LGTM! Comprehensive code examples for both platforms.The code examples provide clear implementation guidance for both React and vanilla HTML/JavaScript, with proper placeholder values that users can easily identify and replace.
docs.json (8)
12-19
: LGTM! Enhanced contextual options.The expanded contextual options including AI assistants (ChatGPT, Claude) and development tools (Cursor, VSCode) provide better integration capabilities for users.
28-30
: LGTM! Simplified navigation structure.The streamlined getting started section focusing on the introduction page is clean and appropriate.
102-105
: LGTM! Clear partner documentation organization.The partner pages are well-organized with descriptive names that clearly indicate their purpose.
124-127
: LGTM! Well-structured open source section.The open source documentation is appropriately organized with logical page grouping.
139-141
: Good API documentation restructuring.The transition from "tokens" to separate "api-keys" and "publishable-keys" pages provides better clarity and organization for different authentication methods.
159-159
: LGTM! Clear distinction for web-based SDKs.Renaming "Client-side SDK" to "Client-side SDK (Web)" provides better clarity and prepares for the mobile SDK distinction.
187-196
: LGTM! Well-structured mobile SDK documentation.The new "Client-side SDK (Mobile)" section is logically organized with a clear introduction page and dedicated installation guides subsection for Swift.
499-499
: Verify that the JSON structure is valid.The trailing line appears to be the closing brace for the JSON structure. Ensure this maintains valid JSON syntax.
concepts/deep-links/quickstart.mdx (8)
61-61
: LGTM! Improved Apple documentation link.The addition of the hyperlink to Apple's official documentation provides better user experience and direct access to authoritative information.
69-69
: LGTM! More descriptive placeholder format.The updated placeholder format
<YOUR_APPLICATION_IDENTIFIER_PREFIX>.<YOUR_APPLICATION_BUNDLE_IDENTIFIER>
is clearer and follows Apple's documentation conventions better than the generic "YOUR_APP_ID".
106-112
: LGTM! Improved terminology and Android support.The change from "Whitelist" to "Allowlist" uses more inclusive terminology, and the addition of Android app link verification guidance makes this section more comprehensive for both platforms.
189-195
: LGTM! Clear option structure and SDK integration.The restructuring to present SDK usage as "Option 1" with a clear link to the Swift installation guide provides excellent user guidance and promotes the use of the official SDK.
196-258
: LGTM! Comprehensive iOS SDK integration examples.The SwiftUI and UIKit code examples are well-structured and demonstrate:
- Proper SDK integration with environment variables
- Handling both app launch and URL opening scenarios
- Async/await pattern for modern Swift development
- Error handling with DubError
- Clear separation of tracking and navigation logic
The code follows iOS development best practices.
261-261
: LGTM! Clear fallback option.Providing "Option 2" for manual handling ensures users have alternatives if they prefer not to use the SDK or need more control.
304-333
: LGTM! Enhanced iOS platform coverage.The addition of the SwiftUI example complements the existing UIKit example, providing comprehensive coverage for both iOS development approaches. The SwiftUI code properly uses the
.onOpenURL
modifier which is the appropriate way to handle deep links in SwiftUI.
317-333
: Verify SwiftUI deep link handling implementation.The SwiftUI example shows calling
trackDeepLinkClick(deepLink: url.absoluteString)
but this function isn't defined in the code block. Users might be confused about where this function comes from.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (6)
conversions/leads/next-auth.mdx (1)
40-66
: Fix undefineduser
in NextAuth event samples.In both App and Pages Router examples,
user
is referenced but never defined. Destructureuser
(andisNewUser
) from the event payload.- events: { - async signIn(message) { - // if it's a new sign up - if (message.isNewUser) { + events: { + async signIn({ user, isNewUser }) { + // if it's a new sign up + if (isNewUser) { const cookieStore = await 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, });- events: { - async signIn(message) { - // if it's a new sign up - if (message.isNewUser) { + events: { + async signIn({ user, isNewUser }) { + // if it's a new sign up + if (isNewUser) { // check if dub_id cookie is present const { dub_id } = req.cookies; 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, }); } } }, },Also applies to: 75-97
conversions/leads/introduction.mdx (3)
58-61
: Incorrect cookie deletion API in Node example.
res.cookies.set
is not valid in Express or Next.js Pages Router. Useres.cookie
(Express) or framework-appropriate APIs.Apply one of these fixes:
- res.cookies.set("dub_id", "", { - expires: new Date(0), - }); + // Express + res.cookie("dub_id", "", { expires: new Date(0), path: "/" });- res.cookies.set("dub_id", "", { - expires: new Date(0), - }); + // Next.js App Router + import { cookies } from "next/headers"; + cookies().delete("dub_id");
87-114
: Go snippet won’t compile: missing imports and wrong field name.Needs
os
,time
, andoperations
import;customerExternalId
must beCustomerExternalId
.Proposed fix:
-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/pkg/models/operations" +) @@ - _, err = d.Track.Lead(context.Background(), &operations.TrackLeadRequest{ - ClickId: dubId.Value, - EventName: "Sign Up", - customerExternalId: customer.ID, - CustomerName: customer.Name, - CustomerEmail: customer.Email, - CustomerAvatar: customer.Avatar, - }) + _, err = d.Track.Lead(context.Background(), &operations.TrackLeadRequest{ + ClickId: dubId.Value, + EventName: "Sign Up", + CustomerExternalId: customer.ID, + CustomerName: customer.Name, + CustomerEmail: customer.Email, + CustomerAvatar: customer.Avatar, + })
152-160
: PHP typo breaks request payload.
customerNasme
should becustomerName
.- $request->customerNasme = $customer->name; + $request->customerName = $customer->name;conversions/leads/supabase.mdx (1)
95-101
: Avoid using Service Role key for auth exchange in Pages Router.
SUPABASE_SERVICE_ROLE_KEY
is over-privileged for this flow; prefer an admin client only when necessary. Consider using an RPC or server helper that doesn’t expose SRK in route code.Update guidance to minimize SRK usage and document risks (scope, rotation, storage). If SRK is required, ensure route is protected and never shipped client-side.
snippets/client-side-tracking-install.mdx (1)
16-16
: Move import to top-level.MDX imports must be at the file’s top. Importing
DubClientInstall
mid-file can break the build.+import DubClientInstall from "/snippets/dub-client-install.mdx"; @@ -import DubClientInstall from "/snippets/dub-client-install.mdx";
🧹 Nitpick comments (7)
conversions/leads/better-auth.mdx (1)
11-11
: Remove unused import or render the snippet.
LeadAttributes
is imported but never used. Either drop the import or render<LeadAttributes />
(consistent with other leads guides) before the outro.Apply one of:
Option A — remove import:
-import LeadAttributes from "/snippets/lead-attributes.mdx";
Option B — render attributes snippet:
import LeadsOutro from "/snippets/leads-outro.mdx"; <LeadsIntro /> ... </Steps> +<LeadAttributes /> <LeadsOutro />
Also applies to: 74-74
conversions/sales/google-tag-manager.mdx (1)
215-225
: Clarify “API Key” as server secret to avoid confusion with publishable keys.Small wording tweak to disambiguate from publishable keys introduced elsewhere.
-**Dub API Key**: Your [Dub API key](https://dub.co/docs/api-reference/api-keys) (starts with `dub_`) +**Dub API Key (server secret)**: Your [Dub API key](https://dub.co/docs/api-reference/api-keys) (starts with `dub_`)conversions/leads/supabase.mdx (2)
63-66
: Harden access to optional user metadata.
user.user_metadata.name
/avatar_url
may be undefined; add safe fallbacks to avoid runtime errors.- customerName: user.user_metadata.name, + customerName: user.user_metadata?.name ?? undefined, @@ - customerAvatar: user.user_metadata.avatar_url, + customerAvatar: user.user_metadata?.avatar_url ?? undefined,Also applies to: 116-119
58-67
: Operational note on waitUntil.
waitUntil
is Vercel-specific; add a note/fallback (e.g.,.catch(console.error)
) for other hosts.snippets/client-side-tracking-install.mdx (2)
20-21
: Clarify key type and secrecy.Add a warning to never embed secret API keys; only use publishable keys client-side.
-You must configure the **publishable key** you generated in step 1 when installing the analytics script. Without this key, client-side conversion tracking will not work. +You must configure the **publishable key** from step 1. Never embed your secret API key in client code. Without the publishable key, client-side conversion tracking will not work.
31-36
: React sample references undefinedinter
.Replace with a plain className to avoid confusion/copy‑paste errors.
- <body className={inter.className}>{children}</body> + <body>{children}</body>docs.json (1)
361-363
: Collapse 2‑hop redirect chain for click tracking.Avoid chaining: point /conversions/clicks/introduction directly to the final destination.
Apply:
- { - "source": "/conversions/clicks/introduction", - "destination": "/sdks/client-side/features/client-side-click-tracking" - }, + { + "source": "/conversions/clicks/introduction", + "destination": "/sdks/client-side/features/click-tracking" + },Also applies to: 413-415
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (19)
concepts/deep-links/deferred-deep-linking.mdx
(5 hunks)conversions/leads/appwrite.mdx
(2 hunks)conversions/leads/auth0.mdx
(2 hunks)conversions/leads/better-auth.mdx
(1 hunks)conversions/leads/clerk.mdx
(2 hunks)conversions/leads/deferred.mdx
(1 hunks)conversions/leads/google-tag-manager.mdx
(3 hunks)conversions/leads/introduction.mdx
(2 hunks)conversions/leads/next-auth.mdx
(2 hunks)conversions/leads/segment.mdx
(2 hunks)conversions/leads/supabase.mdx
(2 hunks)conversions/quickstart.mdx
(1 hunks)conversions/sales/google-tag-manager.mdx
(2 hunks)conversions/sales/shopify.mdx
(1 hunks)docs.json
(8 hunks)snippets/client-side-lead-tracking.mdx
(2 hunks)snippets/client-side-tracking-install.mdx
(1 hunks)snippets/dub-client-mobile-install.mdx
(1 hunks)snippets/leads-intro.mdx
(1 hunks)
✅ Files skipped from review due to trivial changes (1)
- conversions/leads/deferred.mdx
🚧 Files skipped from review as they are similar to previous changes (6)
- concepts/deep-links/deferred-deep-linking.mdx
- snippets/leads-intro.mdx
- conversions/leads/google-tag-manager.mdx
- conversions/quickstart.mdx
- conversions/sales/shopify.mdx
- snippets/dub-client-mobile-install.mdx
🔇 Additional comments (25)
conversions/sales/google-tag-manager.mdx (1)
13-15
: Plan requirement note reads well.Business plan requirement and link look good.
conversions/leads/appwrite.mdx (2)
10-11
: Import rename LGTM.Path and symbol rename to
LeadAttributes
are consistent.
236-236
: Good placement of the attributes reference.Rendering
<LeadAttributes />
after the guide is consistent with other pages.conversions/leads/clerk.mdx (2)
10-10
: Import rename LGTM.
236-236
: Attributes snippet usage LGTM.conversions/leads/auth0.mdx (2)
10-10
: Import rename LGTM.
66-66
: Attributes snippet usage LGTM.conversions/leads/next-auth.mdx (2)
10-10
: Import rename LGTM.
111-111
: Attributes snippet usage LGTM.snippets/client-side-lead-tracking.mdx (3)
1-1
: Import rename LGTM.
88-88
: Attributes snippet usage LGTM.
1-1
: Verify repo-wide rename completeness and snippet existence — unable to confirm (no output).The verification script returned no output; I could not confirm removal of any lingering "LeadsAttributes" references or presence of "lead-attributes.mdx"/"sale-attributes.mdx". Re-run from the repo root and paste the results:
rg -nP '\bLeadsAttributes\b|/snippets/leads-attributes\.mdx' || echo "no matches" fd -a 'lead-attributes.mdx' --type f || echo "not found" fd -a 'sale-attributes.mdx' --type f || echo "not found" rg -nP '/docs/api-reference/api-keys|/docs/api-reference/publishable-keys' docs || trueconversions/leads/segment.mdx (2)
10-10
: Import rename LGTM.
136-136
: Attributes snippet usage LGTM.conversions/leads/introduction.mdx (2)
11-11
: Rename looks consistent.Import path and component name updated to LeadAttributes; matches the usage below.
170-171
: LeadAttributes placement LGTM.Snippet inclusion is correct post-rename.
conversions/leads/supabase.mdx (2)
10-11
: Rename is correct.Import of LeadAttributes matches usage below.
140-151
: LeadAttributes placement LGTM.Consistent with other pages.
snippets/client-side-tracking-install.mdx (1)
55-57
: Script example LGTM.
defer
+data-publishable-key
attribute usage looks correct.docs.json (6)
28-30
: LGTM: Getting Started nav.Explicit single-page list is fine and consistent.
109-112
: LGTM: Partners nav.Slugs look consistent with existing redirects.
131-134
: LGTM: Open source nav.Matches current sections.
165-165
: LGTM: “Client-side SDK (Web)” label.Clearer naming; no slug changes.
193-202
: Ensure mobile pages exist; add redirects for root and iOS paths.
No matching files found for these slugs — confirm they exist or add redirects:
- sdks/client-side-mobile/introduction
- sdks/client-side-mobile/installation-guides/swift
Suggested redirects (add to redirects array):- { "source": "/sdks/client-side-mobile", "destination": "/sdks/client-side-mobile/introduction" }
- { "source": "/sdks/ios", "destination": "/sdks/client-side-mobile/installation-guides/swift" }
- { "source": "/sdks/ios/installation", "destination": "/sdks/client-side-mobile/installation-guides/swift" }
File: docs.json (lines 193-202)
145-147
: Add redirect from /api-reference/tokens → /api-reference/api-keys; confirm target pages existVerification script produced no matches; I could not find api-reference/api-keys or api-reference/publishable-keys in the repo — add the redirect below and confirm those pages exist (e.g., api-reference/api-keys.mdx).
@@ "redirects": [ + { + "source": "/api-reference/tokens", + "destination": "/api-reference/api-keys" + },
docs.json
Outdated
"options": [ | ||
"copy", | ||
"view", | ||
"chatgpt", | ||
"claude", | ||
"cursor", | ||
"vscode" | ||
] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
🧩 Analysis chain
Validate contextual.options values (ChatGPT/Claude/Cursor/VSCode).
Ensure Mintlify supports these option identifiers; unknown values will be ignored or could surface UI nits.
🌐 Web query:
Mintlify docs.json "contextual.options" — what option keys are supported, and are "chatgpt", "claude", "cursor", and "vscode" valid?
💡 Result:
Short answer: The built-in keys supported in docs.json contextual.options are: "copy", "view", "chatgpt", "claude", and "perplexity". "chatgpt" and "claude" are valid. "cursor" and "vscode" are not built‑in keys — you can add those integrations only by creating a custom option object (title/icon/href) in the options array. [1]
Source: Mintlify contextual menu docs. [1]
Replace or convert unsupported contextual.options entries (cursor, vscode).
Mintlify built‑ins are "copy", "view", "chatgpt", "claude", and "perplexity". "cursor" and "vscode" are not built‑in and will be ignored — remove them or replace each with a custom option object (title/icon/href).
File: docs.json — lines 12–19
🤖 Prompt for AI Agents
In docs.json around lines 12 to 19, the options array contains non‑built‑in
entries "cursor" and "vscode" which will be ignored; remove those entries or
convert each into a valid custom option object with the required fields (title,
icon, href) so Mintlify recognizes them (or replace them with a supported
built‑in like "perplexity" if that was intended). Ensure the resulting options
array only includes built‑ins ("copy","view","chatgpt","claude","perplexity") or
properly shaped objects for any custom entries.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
concepts/deep-links/quickstart.mdx (1)
61-75
: AASA sample likely disables Universal Links (paths: []).An empty paths array matches nothing. Recommend allowing all paths (or document a restrictive pattern).
- "paths": [] + "paths": ["*"]If you prefer components-based matching, we can propose that variant instead.
🧹 Nitpick comments (5)
concepts/deep-links/attribution.mdx (3)
39-41
: Grammar fix: “need generate” → “need to generate”.Small copy edit for clarity.
-Then, you'll need generate a [publishable key](/api-reference/publishable-keys) from your Dub workspace to track conversions on the client-side. +Then, you'll need to generate a [publishable key](/api-reference/publishable-keys) from your Dub workspace to track conversions on the client side.
52-68
: Minor style nit: “Mobile SDK” capitalization.Consider “client-side mobile SDK” for consistency with other pages.
149-164
: Avoid logging PII in examples.trackLead parameters include name/email; printing full responses can leak PII in logs. Recommend masking or removing prints in sample code.
- print(response) + // Consider logging minimal metadata or using debug-only logs. + print("Lead tracked successfully")concepts/deep-links/quickstart.mdx (1)
316-333
: Manual SwiftUI example — consistent with Option 2.Looks fine; consider a brief note reminding devs to navigate using the resolved link.url.
- // Call the tracking endpoint with the full deep link URL - trackDeepLinkClick(deepLink: url.absoluteString) + // Call the tracking endpoint, then navigate using the resolved link.url from the response + trackDeepLinkClick(deepLink: url.absoluteString)snippets/dub-analytics-install.mdx (1)
32-47
: Place inside for valid HTML and predictable hydration.In the snippet, the component is rendered outside
<body>
. It should be inside<body>
in Next.js app router layouts.Apply this diff:
return ( <html lang="en"> - <body>{children}</body> - <DubAnalytics /> + <body> + {children} + <DubAnalytics /> + </body> </html> );
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (10)
api-reference/publishable-keys.mdx
(1 hunks)concepts/deep-links/attribution.mdx
(1 hunks)concepts/deep-links/quickstart.mdx
(5 hunks)partners/quickstart.mdx
(1 hunks)sdks/client-side/installation-guides/google-tag-manager.mdx
(1 hunks)sdks/client-side/introduction.mdx
(3 hunks)sdks/client-side/variants.mdx
(1 hunks)snippets/client-side-click-tracking-addendum.mdx
(2 hunks)snippets/dub-analytics-install.mdx
(2 hunks)snippets/steps/generate-publishable-key.mdx
(1 hunks)
✅ Files skipped from review due to trivial changes (2)
- snippets/client-side-click-tracking-addendum.mdx
- sdks/client-side/variants.mdx
🚧 Files skipped from review as they are similar to previous changes (3)
- api-reference/publishable-keys.mdx
- snippets/steps/generate-publishable-key.mdx
- sdks/client-side/introduction.mdx
🔇 Additional comments (13)
concepts/deep-links/attribution.mdx (6)
7-13
: Verify imported snippet/component paths and usage.Confirm these MDX paths exist (especially /snippets/dub-client-mobile-installation-guides.mdx) and that intended components are used. If not needed, consider removing the import to avoid bundle warnings.
15-18
: Plan gating consistency check (Business vs Pro).This page states Business plan is required for deep link attribution, while Quickstart mentions Pro for deep links. If intended, clarify the distinction; otherwise align the plan note.
41-49
: Asset/link verification.Ensure the Analytics settings link and the image path (/images/conversions/publishable-key.png) resolve in the deployed docs.
73-101
: LGTM on first-launch + onOpenURL pattern.The guidance to call trackOpen once on first launch and again with a deepLink looks correct.
166-174
: Clarify amount units and currency casing.Specify whether amount is minor units (e.g., cents) and whether currency must be lowercase "usd" or ISO 4217 uppercase "USD" per API/SDK.
198-202
: Anchor/link check.Confirm the server-side quickstart anchor (#step-3%3A-install-the-dub-server-side-sdk-%2B-track-conversion-events) exists post-build; encoded anchors can drift.
concepts/deep-links/quickstart.mdx (3)
106-113
: LGTM on allowlist terminology and links.Terminology update and Apple/Android refs look good.
189-197
: LGTM: SDK-first option callout.Clear positioning of the SDK vs manual handling.
303-314
: Manual UIKit example — OK to keep under Option 2.This aligns with the manual approach; once the duplicate in Option 1 is removed, this will be the single UIKit example.
Please confirm there’s no requirement for a publishable key or auth header on /track/open in client contexts; if required, add it to the examples.
partners/quickstart.mdx (1)
42-44
: Verified — anchor and path are correct.Heading "## Automatically fetching partner and discount data" is present in sdks/client-side/features/click-tracking.mdx (line 121), matching the slug #automatically-fetching-partner-and-discount-data; no changes required.
sdks/client-side/installation-guides/google-tag-manager.mdx (1)
50-50
: Confirm data-domains JSON shape & key namesPath update LGTM; confirm the runtime reads the script tag's data-domains (dataset.domains) and expects JSON with a refer field (e.g. script.dataset.domains = JSON.stringify({ refer: "refer.yourdomain.com" })) — ensure the attribute is 'domains' (not 'domainsConfig') and the field is 'refer'. File: sdks/client-side/installation-guides/google-tag-manager.mdx (line ~50). No parser was found in the repo search; manually verify the client-side code that parses data-domains.
snippets/dub-analytics-install.mdx (2)
53-53
: domainsConfig.refer is correct; no change required.
Verified 'refer' is the documented key in multiple files: snippets/dub-analytics-params-react.mdx (ParamField), sdks/client-side/features/click-tracking.mdx (example), and dub-analytics.js (data-domains).
74-74
: Approve — target guide and anchors validated.sdks/client-side/features/click-tracking.mdx exists; headings produce slugs including "automatically-fetching-partner-and-discount-data" (line 121) and "manually-tracking-clicks-with-the-trackclick-function" (line 207); partners/quickstart.mdx links to /sdks/client-side/features/click-tracking#automatically-fetching-partner-and-discount-data which matches — no action required.
```swift iOS (SwiftUI) | ||
// ContentView.swift | ||
import SwiftUI | ||
import Dub | ||
|
||
struct ContentView: View { | ||
|
||
@Environment(\.dub) var dub: Dub | ||
|
||
@AppStorage("is_first_launch") private var isFirstLaunch = true | ||
|
||
var body: some View { | ||
NavigationStack { | ||
VStack { | ||
// Your app content | ||
} | ||
.onOpenURL { url in | ||
trackOpen(deepLink: url) | ||
} | ||
.onAppear { | ||
if isFirstLaunch { | ||
trackOpen() | ||
isFirstLaunch = false | ||
} | ||
} | ||
} | ||
} | ||
|
||
private func trackOpen(deepLink: URL? = nil) { | ||
Task { | ||
do { | ||
let response = try await dub.trackOpen(deepLink: deepLink) | ||
|
||
// Obtain the destination URL from the response | ||
guard let url = response.link?.url else { | ||
return | ||
} | ||
|
||
// Navigate to the destination URL | ||
} catch let error as DubError { | ||
print(error.localizedDescription) | ||
} | ||
} | ||
} | ||
} | ||
``` | ||
|
||
```swift iOS (UIKit) | ||
// AppDelegate.swift | ||
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool { | ||
handleDeepLink(url: url) | ||
return true | ||
} | ||
|
||
func handleDeepLink(url: URL) { | ||
// Call the tracking endpoint with the full deep link URL | ||
trackDeepLinkClick(deepLink: url.absoluteString) | ||
} | ||
``` | ||
|
||
</CodeGroup> | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
UIKit snippet here is “manual,” not SDK-based — and duplicated below.
Under “Option 1 (SDK)”, the UIKit example calls a custom trackDeepLinkClick and doesn’t use the SDK. Either replace with a true SDK UIKit example or remove this block and keep UIKit-only manual flow under Option 2 to avoid duplication.
-```swift iOS (UIKit)
-// AppDelegate.swift
-func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
- handleDeepLink(url: url)
- return true
-}
-
-func handleDeepLink(url: URL) {
- // Call the tracking endpoint with the full deep link URL
- trackDeepLinkClick(deepLink: url.absoluteString)
-}
-```
+<!-- UIKit sample removed here to avoid duplicating the manual approach under Option 2.
+ If an SDK-based UIKit snippet is available, insert it here instead. -->
🤖 Prompt for AI Agents
In concepts/deep-links/quickstart.mdx around lines 198 to 259, the UIKit snippet
under "Option 1 (SDK)" is a manual, non-SDK implementation and duplicates the
manual flow shown later (Option 2); replace or remove it to avoid duplication.
Either swap the current AppDelegate example for a proper SDK-based UIKit example
(calling the SDK's deep-link tracking method and showing how to hook into
application(_:open:options:)), or remove this block and add the comment shown in
the review ("UIKit sample removed...") so only the manual flow remains under
Option 2; ensure the file contains no duplicated manual examples and that
headings reflect which option is SDK vs manual.
client-side SDK (mobile)
docsSummary by CodeRabbit
New Features
Documentation