免费获取学习方案
ARTICLE DETAIL

资讯详情

深耕编程基础知识与建站技术分享的一线实战洞察。

Dub × Appwrite 集成指南:在 Next.js 注册流程中追踪 Lead 转化事件

Dub × Appwrite 集成指南:在 Next.js 注册流程中追踪 Lead 转化事件 Dub × Appwrite 集成指南在 Next.js 注册流程中追踪 Lead 转化事件【免费下载链接】dubThe modern link attribution platform. Loved by world-class marketing teams like Framer, Perplexity, Superhuman, Twilio, Buffer and more.项目地址: https://gitcode.com/GitHub_Trending/du/dub本指南基于 Dub 开源仓库中的 apps/web/guides/appwrite.md 编写完整讲解如何将 Dub 与 Appwrite 身份认证服务集成当用户在你的 Next.js 应用中完成注册时通过dub.track.lead()将注册行为作为 Lead 转化事件上报给 Dub从而打通用户点击 Dub 短链 → 落地页注册 → 归因到对应点击的完整链路。读完本文你将掌握 Dub 客户端脚本的接入方式、dub_idCookie 的读取与消费逻辑、Appwrite Session/Admin 双客户端的正确用法以及 Lead 事件在 Dub 服务端的处理原理。集成方案总览Dub 的转化归因模型基于点击即留痕的思路用户访问你投放的 Dub 短链时Dub 会在浏览器中写入一个名为dub_id的 Cookie用于标记这次点击的来源clickId。当用户在你的应用内完成注册即发生 Lead 转化时只需把这个dub_id的值连同用户信息通过dub.track.lead()上报Dub 即可将这次转化精确归因到最初的短链点击。因此整个集成包含两条主线客户端打点在应用根布局中挂载DubAnalytics组件由它负责加载 Dub 脚本并在合适时机写入dub_idCookie。服务端上报在注册成功后读取 Cookie 中的dub_id调用 Dub Node.js SDK 的dub.track.lead()发送 Lead 事件随后删除该 Cookie 避免重复上报。这与仓库中其他认证提供方如 clerk.md、auth0.md、supabase.md的集成思路一致注册回调中统一消费dub_idCookie。仓库自身的实现可参考 apps/web/lib/auth/track-dub-lead.ts它在 NextAuth 回调中读取dub_id调用dub.track.lead()后删除dub_id与dub_partner_data两个 Cookie与本文的 Appwrite 方案异曲同工。Step 1创建 Appwrite 项目并配置 API Key前往 Appwrite Cloud 创建一个新项目。创建完成后在项目设置中为你的服务端应用新建一个 API Key并确保勾选sessions.write权限——该权限用于服务端以 Admin 身份代用户创建账号与会话。同时从项目 Settings 页面复制以下两项信息备用Project ID项目唯一标识用于客户端与服务端初始化Client。EndpointAPI 服务地址默认形如https://cloud.appwrite.io/v1。随后在你的 Next.js 项目中安装 Appwrite 官方 Node.js SDKnpm i node-appwrite说明sessions.write是本文示例中 Admin 客户端调用account.create()与account.createEmailPasswordSession()所需的最小权限集。若你的注册流程还涉及读取用户资料、管理其他资源请按实际需要追加对应 scope。Step 2配置环境变量将以下环境变量写入你的应用如.env.localNEXT_PUBLIC_APPWRITE_ENDPOINThttps://cloud.appwrite.io/v1 NEXT_PUBLIC_APPWRITE_PROJECTAPPWRITE_PROJECT_ID NEXT_APPWRITE_KEYAPPWRITE_API_KEY NEXT_DUB_API_KEYDUB_API_KEY各变量职责如下变量用途注意点NEXT_PUBLIC_APPWRITE_ENDPOINTAppwrite API 端点NEXT_PUBLIC_前缀意味着会被打包进浏览器仅暴露端点地址是安全的NEXT_PUBLIC_APPWRITE_PROJECT项目 ID公开给客户端是 Appwrite 的预期用法无安全风险NEXT_APPWRITE_KEYAppwrite API Key仅服务端使用绝不能加NEXT_PUBLIC_前缀防止泄露NEXT_DUB_API_KEYDub API Key同样仅服务端使用用于初始化DubSDK 客户端Dub SDK 初始化时可显式传入 token也可依赖环境变量DUB_API_KEY自动读取。本文示例使用NEXT_DUB_API_KEY显式传参见 manual-track-lead.md 中对 SDK 用法的说明。Step 3在根布局挂载 DubAnalytics 组件在应用根布局app/layout.tsx中引入dub/analytics包提供的Analytics组件别名为DubAnalytics并将其放在body内import type { Metadata } from next; import { Analytics as DubAnalytics } from dub/analytics/react; export const metadata: Metadata { title: Appwrite Dub Leads Example, description: Appwrite Dub Leads Tracking example app with Next.js, }; export default function RootLayout({ children, }: Readonly{ children: React.ReactNode; }) { return ( html langen body{children}/body DubAnalytics / /html ); }这个组件负责加载 Dub 的客户端脚本即https://www.dubcdn.com/analytics/script.js与 manual-client-sdk.md 中手动在head注入的script defer srchttps://www.dubcdn.com/analytics/script.js等价并在页面中完成点击追踪与dub_idCookie 的写入。后续所有 Lead 归因都依赖这个 Cookie 的值因此该组件必须在注册页所在的布局中生效。如果只想用标签管理器方式接入可参考 gtm-client-sdk.md 在 GTM 中配置dub_idCookie 变量。Step 4创建 Appwrite Session 客户端与 Admin 客户端在 SSR服务端渲染场景下你不能在客户端直接使用用户的会话凭据因此需要区分两个客户端这也正是 Appwrite 官方 SSR 文档推荐的做法Session 客户端使用浏览器 Cookie 中的会话my-custom-session初始化代表当前登录用户用于读取用户信息、校验登录态。Admin 客户端使用 API Key 初始化拥有服务端特权用于代用户创建账号与 Email/Password 会话。在lib/server/appwrite.ts中实现use server; import { Client, Account } from node-appwrite; import { cookies } from next/headers; export async function createSessionClient() { const client new Client() .setEndpoint(process.env.NEXT_PUBLIC_APPWRITE_ENDPOINT as string) .setProject(process.env.NEXT_PUBLIC_APPWRITE_PROJECT as string); const session (await cookies()).get(my-custom-session); if (!session || !session.value) { throw new Error(No session); } client.setSession(session.value); return { get account() { return new Account(client); }, }; } export async function createAdminClient() { const client new Client() .setEndpoint(process.env.NEXT_PUBLIC_APPWRITE_ENDPOINT as string) .setProject(process.env.NEXT_PUBLIC_APPWRITE_PROJECT as string) .setKey(process.env.NEXT_APPWRITE_KEY as string); return { get account() { return new Account(client); }, }; }关键点说明createSessionClient从 Cookie 读取名为my-custom-session的会话值并setSession无会话时抛出异常——注意会话名必须与 Step 6 写入 Cookie 时使用的键名保持一致。createAdminClient通过setKey注入服务端 API Key全程只运行在服务端密钥不落浏览器。两个客户端都返回懒加载的account访问器按需实例化Account。Step 5创建 Dub 客户端并上报 Lead创建lib/server/dub.ts初始化 Dub SDK 并封装一个addDubLead函数。它接收 Appwrite 返回的User对象和从 Cookie 取出的dub_id将其映射为 Lead 事件参数import type { Models } from node-appwrite; import { Dub } from dub; const dub new Dub({ token: process.env.NEXT_DUB_API_KEY, }); export function addDubLead( user: Models.UserModels.Preferences, dub_id: string, ) { dub.track.lead({ clickId: dub_id, eventName: Sign Up, customerExternalId: user.$id, customerName: user.name, customerEmail: user.email, }); }各参数与 Dub 服务端track/lead接口的对应关系如下参数定义见 apps/web/app/(ee)/api/track/lead/route.ts/api/track/lead/route.ts) 中的请求解析逻辑参数含义示例取值来源clickId最初的短链点击 ID即dub_idCookie 值dub_id函数入参eventName转化事件名建议语义化命名Sign UpcustomerExternalId客户在你的系统中的唯一 ID用于去重与关联user.$idAppwrite 用户 IDcustomerName客户姓名user.namecustomerEmail客户邮箱user.emailcustomerAvatar可选客户头像 URLuser.image其中customerExternalId是必填字段在服务端接口中若clickId未传会被规范化为空字符串而缺少customerExternalId会直接抛出bad_request错误customerExternalId is required。另外服务端为了向后兼容仍接受旧字段externalId与customerId并优先使用新字段customerExternalId——新代码中请统一使用新字段名。仓库自身在 apps/web/lib/dub.ts 中通过dub.customers.list({ externalId })反查客户印证了customerExternalId承担跨系统关联主键的角色。Step 6在注册 Action 中串联完整链路最后在/auth页面中编写注册 Server Action。流程为用 Admin 客户端创建账号与会话 → 将会话写入 Cookie → 检查dub_idCookie 是否存在 → 存在则调用addDubLead上报 → 删除dub_idCookie → 重定向到成功页。import { ID } from node-appwrite; import { createAdminClient, getLoggedInUser } from /lib/server/appwrite; import { cookies } from next/headers; import { redirect } from next/navigation; import { addDubLead } from /lib/server/dub; async function signUpWithEmail(formData: any) { use server; // Get sign up info from form const email formData.get(email); const password formData.get(password); const name formData.get(name); // Create account and session using Appwrite const { account } await createAdminClient(); const user await account.create(ID.unique(), email, password, name); const session await account.createEmailPasswordSession(email, password); (await cookies()).set(my-custom-session, session.secret, { path: /, httpOnly: true, sameSite: strict, secure: true, }); // Check if Dub ID is present in cookies and track lead if found const dub_id (await cookies()).get(dub_id)?.value; if (dub_id) { addDubLead(user, dub_id); (await cookies()).delete(dub_id); } // Redirect to success page redirect(/auth/success); } export default async function SignUpPage() { // Verify active user session and redirect to success page if found const user await getLoggedInUser(); if (user) redirect(/auth/success); return ( form action{signUpWithEmail} input idemail nameemail placeholderEmail typeemail required / input idpassword namepassword placeholderPassword minLength{8} typepassword required / input idname namename placeholderName typetext required / button typesubmitSign up/button /form / ); }本节涉及的三个实现要点均可在仓库中找到同源佐证会话 Cookie 属性httpOnly: true防止 XSS 读取会话sameSite: strict降低 CSRF 风险secure: true要求 HTTPS 传输path: /保证全站可读。dub_id的读取与清理仓库的 apps/web/lib/auth/track-dub-lead.ts 采用完全相同的模式——先cookies().get(dub_id)无值则跳过上报有值则dub.track.lead()后cookieStore.delete(dub_id)避免同一点击被重复记录。登录态守卫getLoggedInUser()复用createSessionClient校验会话已登录用户直接跳转成功页防止重复注册。深入原理Lead 事件到达 Dub 服务端后发生了什么理解服务端处理链路有助于排查事件未上报类问题。dub.track.lead()最终会向POST https://api.dub.co/track/lead发起请求。在 Dub 服务端该端点由 apps/web/app/(ee)/api/track/lead/route.ts/api/track/lead/route.ts) 实现核心流程如下请求经过withWorkspace鉴权中间件并校验当前工作区套餐需为business、advanced或enterprise之一即 Lead 追踪是付费能力角色需为owner或member。请求体经trackLeadRequestSchema解析clickId缺省时规范化为空字符串customerExternalId兼容旧的externalId/customerId字段。调用 apps/web/lib/api/conversions/track-lead.ts 中的trackLead()从 Tinybird 查询对应的getClickEvent依据 clickId写入 Lead 事件数据、创建或关联客户记录、触发工作流、推送 Webhook、向合作伙伴队列下发佣金结算、上传 Google Ads 转化等。因此从端到端视角看本文 Step 3 的DubAnalytics负责种 CookieStep 6 的addDubLead负责收 Cookie 并上报服务端track/lead负责归因与分发。任何一环缺失如布局未挂载组件、上报前误删 Cookie、套餐无权限都会导致归因失败。验证与排错建议确认dub_idCookie 存在打开落地页开发者工具 → Application → Cookies应能看到dub_id该值即clickId。确认注册后上报注册成功后该 Cookie 应被删除说明上报逻辑已执行。确认套餐权限track/lead需要 business 及以上套餐开发环境请核对工作区套餐否则接口会返回权限错误。参考手动上报若想跳过 UI 直接验证接口可参照 manual-track-lead.md 中的 REST 示例向https://api.dub.co/track/lead发送带Authorization: Bearer dub_xxx头的 JSON 请求检查返回状态与数据。同类集成对照如果后续要接入其他认证服务商可对照 clerk.md、auth0.md、supabase.md 等指南它们的核心都是注册回调中读取dub_id→ 上报 → 清理 Cookie可以相互印证。【免费下载链接】dubThe modern link attribution platform. Loved by world-class marketing teams like Framer, Perplexity, Superhuman, Twilio, Buffer and more.项目地址: https://gitcode.com/GitHub_Trending/du/dub创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表