---
title: "Overview"
description: "Dub is the modern link attribution platform engineered for short links, real-time conversion tracking, and scalable affiliate programs. This system overview explores the underlying architecture and..."
last_updated: "2026-10-05T05:07:35.143771+00:00"
canonical_url: "https://www.doc0.dev/docs/934e554a-e6a1-476f-bb2f-23e62d86c3fd/technical/getting-started/overview"
---

<details>
<summary>Relevant source files</summary>

The following files were used as context for generating this wiki page:

- [apps/web/lib/dub.ts](https://github.com/blade47/dub/blob/HEAD/apps/web/lib/dub.ts)
- [apps/web/lib/openapi/index.ts](https://github.com/blade47/dub/blob/HEAD/apps/web/lib/openapi/index.ts)
- [apps/web/app/app.dub.co/dashboard/slug/ee/program/page.tsx](https://github.com/blade47/dub/blob/HEAD/apps/web/app/app.dub.co/(dashboard)/%5Bslug%5D/(ee)/program/page.tsx)
- [apps/web/ui/placeholders/features-section.tsx](https://github.com/blade47/dub/blob/HEAD/apps/web/ui/placeholders/features-section.tsx)
- [apps/web/app/ee/app.dub.co/embed/referrals/quickstart.tsx](https://github.com/blade47/dub/blob/HEAD/apps/web/app/(ee)/app.dub.co/embed/referrals/quickstart.tsx)
- [apps/web/app/ee/app.dub.co/new-program/slug/program/new/overview/page.tsx](https://github.com/blade47/dub/blob/HEAD/apps/web/app/(ee)/app.dub.co/(new-program)/%5Bslug%5D/program/new/overview/page.tsx)
- [apps/web/app/domain/page.tsx](https://github.com/blade47/dub/blob/HEAD/apps/web/app/%5Bdomain%5D/page.tsx)
- [apps/web/app/app.dub.co/onboarding/onboarding/steps/welcome/page.tsx](https://github.com/blade47/dub/blob/HEAD/apps/web/app/app.dub.co/(onboarding)/onboarding/(steps)/welcome/page.tsx)
- [packages/hubspot-app/hsproject.json](https://github.com/blade47/dub/blob/HEAD/packages/hubspot-app/hsproject.json)
- [apps/web/app/app.dub.co/onboarding/onboarding/steps/products/page.tsx](https://github.com/blade47/dub/blob/HEAD/apps/web/app/app.dub.co/(onboarding)/onboarding/(steps)/products/page.tsx)
- [apps/web/app/app.dub.co/onboarding/onboarding/steps/plan/page.tsx](https://github.com/blade47/dub/blob/HEAD/apps/web/app/app.dub.co/(onboarding)/onboarding/(steps)/plan/page.tsx)
- [packages/ui/src/content.ts](https://github.com/blade47/dub/blob/HEAD/packages/ui/src/content.ts)
- [packages/cli/src/index.ts](https://github.com/blade47/dub/blob/HEAD/packages/cli/src/index.ts)
- [packages/ui/src/nav/content/product-content.tsx](https://github.com/blade47/dub/blob/HEAD/packages/ui/src/nav/content/product-content.tsx)
- [packages/ui/src/footer.tsx](https://github.com/blade47/dub/blob/HEAD/packages/ui/src/footer.tsx)
- [apps/web/app/ee/partners.dub.co/dashboard/programs/programSlug/enrolled/page.tsx](https://github.com/blade47/dub/blob/HEAD/apps/web/app/(ee)/partners.dub.co/(dashboard)/programs/%5BprogramSlug%5D/(enrolled)/page.tsx)
- [apps/web/app/app.dub.co/onboarding/onboarding/steps/success/page-client.tsx](https://github.com/blade47/dub/blob/HEAD/apps/web/app/app.dub.co/(onboarding)/onboarding/(steps)/success/page-client.tsx)
- [apps/web/app/ee/app.dub.co/layout.tsx](https://github.com/blade47/dub/blob/HEAD/apps/web/app/(ee)/app.dub.co/layout.tsx)
- [apps/web/app/app.dub.co/dashboard/layout.tsx](https://github.com/blade47/dub/blob/HEAD/apps/web/app/app.dub.co/(dashboard)/layout.tsx)
- [packages/cli/src/types/index.ts](https://github.com/blade47/dub/blob/HEAD/packages/cli/src/types/index.ts)
- [packages/stripe-app/src/utils/constants.ts](https://github.com/blade47/dub/blob/HEAD/packages/stripe-app/src/utils/constants.ts)
- [apps/web/app/app.dub.co/deeplink/deeplink/domain/...key/page.tsx](https://github.com/blade47/dub/blob/HEAD/apps/web/app/app.dub.co/(deeplink)/deeplink/%5Bdomain%5D/%5B%5B...key%5D%5D/page.tsx)
- [packages/utils/src/constants/main.ts](https://github.com/blade47/dub/blob/HEAD/packages/utils/src/constants/main.ts)
- [packages/embeds/core/src/embed.ts](https://github.com/blade47/dub/blob/HEAD/packages/embeds/core/src/embed.ts)
- [apps/web/app/app.dub.co/marketplace/layout.tsx](https://github.com/blade47/dub/blob/HEAD/apps/web/app/app.dub.co/marketplace/layout.tsx)
- [packages/ui/src/nav/content/resources-content.tsx](https://github.com/blade47/dub/blob/HEAD/packages/ui/src/nav/content/resources-content.tsx)
- [apps/web/app/app.dub.co/auth-marketing/register/page.tsx](https://github.com/blade47/dub/blob/HEAD/apps/web/app/app.dub.co/(auth-marketing)/register/page.tsx)
- [apps/web/app/app.dub.co/onboarding/onboarding/steps/layout.tsx](https://github.com/blade47/dub/blob/HEAD/apps/web/app/app.dub.co/(onboarding)/onboarding/(steps)/layout.tsx)
- [packages/email/src/templates/welcome-email.tsx](https://github.com/blade47/dub/blob/HEAD/packages/email/src/templates/welcome-email.tsx)
- [packages/utils/src/constants/pricing/pricing-plan-compare-features.tsx](https://github.com/blade47/dub/blob/HEAD/packages/utils/src/constants/pricing/pricing-plan-compare-features.tsx)
</details>

## Overview

Dub is the modern link attribution platform engineered for short links, real-time conversion tracking, and scalable affiliate programs. This system overview explores the underlying architecture and developer toolchains powering Dub, encompassing its monorepo layout, OpenAPI-driven REST interface, custom domain infrastructure, onboarding pathways, enterprise partner programs, and extensible third-party ecosystem integrations.

Sources: [apps/web/lib/openapi/index.ts:28-32](https://github.com/blade47/dub/blob/HEAD/apps/web/lib/openapi/index.ts#L28-L32)

## Platform Architecture and Monorepo Layout

### Overview

Dub is structured as a robust monorepo organizing distinct application runtimes, shared component libraries, utility modules, and template rendering engines. The codebase divides responsibilities across specialized packages and Next.js applications, governing hostnames, environment bindings, SDK integrations, and transactional messaging.

Sources: [apps/web/lib/dub.ts:1-3](https://github.com/blade47/dub/blob/HEAD/apps/web/lib/dub.ts#L1-L3), [packages/utils/src/constants/main.ts:1-58](https://github.com/blade47/dub/blob/HEAD/packages/utils/src/constants/main.ts#L1-L58)

### Core System Hostnames and Environments

The infrastructure relies on explicit environment variables and runtime checks to partition API routing, partner portals, and core application domains across production, staging, and local development environments.

| Constant Name | Production / Staging Value | Local / Fallback Value | Purpose |
| :--- | :--- | :--- | :--- |
| `API_DOMAIN` | `https://api.dub.co` / `https://api-staging.dub.co` | `http://api.localhost:8888` | Base URL for REST API endpoints |
| `PARTNERS_DOMAIN` | `https://partners.dub.co` / `https://partners-staging.dub.co` | `http://partners.localhost:8888` | Base URL for the partner program portal |
| `APP_DOMAIN` | `https://app.dub.co` / `https://${NEXT_PUBLIC_VERCEL_URL}` | `http://localhost:8888` | Base URL for the primary Next.js web application |
| `SHORT_DOMAIN` | `dub.sh` | `dub.sh` | Default short link domain suffix |

Sources: [packages/utils/src/constants/main.ts:1-58](https://github.com/blade47/dub/blob/HEAD/packages/utils/src/constants/main.ts#L1-L58)

> [!NOTE]
> Preview environments utilize dynamic Vercel URL patterns for app hostnames, whereas preview API and partner domains rely explicitly on their respective staging subdomains (`api-staging.dub.co` and `partners-staging.dub.co`).

Sources: [packages/utils/src/constants/main.ts:11-58](https://github.com/blade47/dub/blob/HEAD/packages/utils/src/constants/main.ts#L11-L58)

### Shared UI Packages and Navigation

The user interface layer (`packages/ui`) exports consolidated navigation taxonomies, layout wrappers, and design primitives utilized across web views. This includes product feature arrays, legal document lists, and official SDK metadata.

```typescript
export const SDKS = [
  { icon: Typescript, href: "/sdks/typescript", title: "Typescript" },
  { icon: Python, href: "/sdks/python", title: "Python" },
  { icon: Go, href: "/sdks/go", title: "Go" },
  { icon: Ruby, href: "/sdks/ruby", title: "Ruby" },
  { icon: Php, href: "/sdks/php", title: "PHP" },
];
```

Sources: [packages/ui/src/content.ts:81-115](https://github.com/blade47/dub/blob/HEAD/packages/ui/src/content.ts#L81-L115)

The platform UI also maintains strict categorization for product solutions, secondary resource directories, and social handles.

| Category | Representative Items | Target Slugs / URLs |
| :--- | :--- | :--- |
| **Features List** | Partners, Analytics, Links, API, Integrations | `/partners`, `/analytics`, `/links`, `/integrations` |
| **Solutions** | Affiliate Management, Marketing Attribution, Creators | `/partners`, `/analytics`, `/solutions/creators` |
| **Legal Pages** | Privacy Policy, Terms of Service, SLA, DPA | `privacy`, `terms`, `sla`, `dpa` |
| **Social Channels** | X (Twitter), LinkedIn, GitHub, YouTube | External platform links |

Sources: [packages/ui/src/content.ts:44-79](https://github.com/blade47/dub/blob/HEAD/packages/ui/src/content.ts#L44-L79), [packages/ui/src/content.ts:117-140](https://github.com/blade47/dub/blob/HEAD/packages/ui/src/content.ts#L117-L140), [packages/ui/src/content.ts:206-234](https://github.com/blade47/dub/blob/HEAD/packages/ui/src/content.ts#L206-L234)

### Email Template Architecture

The email package (`packages/email`) builds responsive transactional notifications utilizing `@react-email/components` and Tailwind CSS. The `WelcomeEmail` workflow handles customer onboarding messages by conditionally parsing workspace slugs, logos, and onboarding step links.

```typescript
export default function WelcomeEmail({
  email = "panic@thedis.co",
  workspace,
  unsubscribeUrl,
}: WelcomeEmailProps) {
  const workspaceUrl = workspace
    ? `https://app.dub.co/${workspace?.slug}`
    : "https://app.dub.co";
  // Renders container, branding, workspace card, and getting started checklist
}
```

Sources: [packages/email/src/templates/welcome-email.tsx:20-36](https://github.com/blade47/dub/blob/HEAD/packages/email/src/templates/welcome-email.tsx#L20-L36)

## Public APIs and Developer Tools

### OpenAPI Specification and REST Architecture

The Dub platform exposes its programmatic interface via an OpenAPI-driven REST specification constructed using `zod-openapi` within `apps/web/lib/openapi/index.ts`. The OpenAPI document is configured with version `0.0.1`, metadata identifying the API as the **Dub API**, and contact/license references.

```typescript
export const document = createDocument({
  openapi: "3.0.3",
  info: {
    title: "Dub API",
    description:
      "Dub is the modern link attribution platform for short links, conversion tracking, and affiliate programs.",
    version: "0.0.1",
    contact: {
      name: "Dub Support",
      email: "support@dub.co",
      url: "https://dub.co/support",
    },
    license: {
      name: "AGPL-3.0 license",
      url: "https://github.com/dubinc/dub/blob/main/LICENSE.md",
    },
  },
  servers: [
    {
      url: "https://api.dub.co",
      description: "Production API",
    },
  ],
  // Paths and components configuration...
});
```

Sources: [apps/web/lib/openapi/index.ts:26-48](https://github.com/blade47/dub/blob/HEAD/apps/web/lib/openapi/index.ts#L26-L48)

The specification aggregates routing modules across core domain endpoints and registers standard schema components and security mechanisms.

| Component Category | Registered Schema / Scheme Entries | Source Reference |
| :--- | :--- | :--- |
| **Component Schemas** | `LinkSchema`, `LinkTagSchema`, `FolderSchema`, `DomainSchema`, `DiscountCodeSchema`, `webhookEventSchema`, `LinkErrorSchema` | [apps/web/lib/openapi/index.ts:68-76](https://github.com/blade47/dub/blob/HEAD/apps/web/lib/openapi/index.ts#L68-L76) |
| **Security Schemes** | `token` (HTTP Bearer authentication with `x-speakeasy-example: DUB_API_KEY`) | [apps/web/lib/openapi/index.ts:77-84](https://github.com/blade47/dub/blob/HEAD/apps/web/lib/openapi/index.ts#L77-L84) |
| **Error Responses** | Standard OpenAPI error response components (`openApiErrorResponsesComponents`) | [apps/web/lib/openapi/index.ts:85-87](https://github.com/blade47/dub/blob/HEAD/apps/web/lib/openapi/index.ts#L85-L87) |

Sources: [apps/web/lib/openapi/index.ts:67-88](https://github.com/blade47/dub/blob/HEAD/apps/web/lib/openapi/index.ts#L67-L88)

The API paths integrated into the document cover all platform subsystems, combining link management, analytics, tracking, customer attribution, partners, payout systems, and embed tokens.

| Path Module Group | Included Path Imports |
| :--- | :--- |
| **Core Links & Organization** | `linksPaths`, `analyticsPath`, `eventsPath`, `tagsPaths`, `foldersPaths`, `domainsPaths` |
| **Attribution & Tracking** | `trackPaths`, `customersPaths`, `partnersPaths`, `programApplicationsPaths`, `discountCodesPaths`, `commissionsPaths`, `payoutsPaths` |
| **Embeds & Tools** | `embedTokensPaths`, `qrCodePaths`, `bountiesPaths` |

Sources: [apps/web/lib/openapi/index.ts:50-66](https://github.com/blade47/dub/blob/HEAD/apps/web/lib/openapi/index.ts#L50-L66)

> [!NOTE]
> The OpenAPI document utilizes Speakeasy annotations (`x-speakeasy-example`) within security scheme definitions to automatically generate strongly-typed public SDKs across multiple languages.

Sources: [apps/web/lib/openapi/index.ts:77-84](https://github.com/blade47/dub/blob/HEAD/apps/web/lib/openapi/index.ts#L77-L84)

### Server-Side SDK Integration

Internal web applications interact with the public API using the official `dub` Node.js client package. For instance, customer record retrieval initializes a client instance and queries customer entities filtering by external database identifiers.

```typescript
import { Dub } from "dub";

export const dub = new Dub();

// fetch Dub customer using their external ID (ID in our database)
export const getDubCustomer = async (userId: string) => {
  try {
    const { result: customers } = await dub.customers.list({
      externalId: userId,
      includeExpandedFields: true,
    });

    return customers.length > 0 ? customers[0] : null;
  } catch (error) {
    console.error(error);
    return null;
  }
};
```

Sources: [apps/web/lib/dub.ts:1-18](https://github.com/blade47/dub/blob/HEAD/apps/web/lib/dub.ts#L1-L18)

### CLI Management Utilities

Management operations can also be executed via the official command-line interface package (`packages/cli`), which is built on top of the `commander` library. Process signal handlers (`SIGINT` and `SIGTERM`) ensure clean exits.

```typescript
#!/usr/bin/env node

import { config } from "@/commands/config";
import { domains } from "@/commands/domains";
import { login } from "@/commands/login";
import { shorten } from "@/commands/shorten";
import { getPackageInfo } from "@/utils/get-package-info";
import { Command } from "commander";
import { links } from "./commands/links";

process.on("SIGINT", () => process.exit(0));
process.on("SIGTERM", () => process.exit(0));

async function main() {
  const packageInfo = await getPackageInfo();

  const program = new Command()
    .name("dub")
    .description("A CLI for shortening links with the Dub API.")
    .version(
      packageInfo.version || "1.0.0",
      "-v, --version",
      "display the version number",
    );

  program
    .addCommand(login)
    .addCommand(config)
    .addCommand(domains)
    .addCommand(shorten)
    .addCommand(links);

  program.parse();
}

main();
```

Sources: [packages/cli/src/index.ts:1-36](https://github.com/blade47/dub/blob/HEAD/packages/cli/src/index.ts#L1-L36)

The CLI configuration and error contracts are typed via dedicated TypeScript interfaces governing local credential persistence and structured API error responses.

| Interface Name | Properties | Purpose |
| :--- | :--- | :--- |
| `DubConfig` | `access_token` (string), `refresh_token` (string \| null), `expires_at` (number \| null), `domain` (optional string) | Manages local CLI authentication state and active domain context |
| `APIError` | `error: { code: string; message: string; doc_url: string }` | Standardized payload structure returned upon encountering API faults |

Sources: [packages/cli/src/types/index.ts:1-14](https://github.com/blade47/dub/blob/HEAD/packages/cli/src/types/index.ts#L1-L14)

## Link Infrastructure and Deep Linking

### Overview

Link infrastructure and deep linking form the core routing mechanisms that translate short URLs, custom domains, and mobile intents into precise destinations. The platform combines dynamic domain welcome pages, feature placeholders, and intelligent deep link preview resolution to handle both web navigation and mobile app deep linking.

Sources: [apps/web/ui/placeholders/features-section.tsx:15-120](https://github.com/blade47/dub/blob/HEAD/apps/web/ui/placeholders/features-section.tsx#L15-L120), [apps/web/app/domain/page.tsx:1-86](https://github.com/blade47/dub/blob/HEAD/apps/web/app/domain/page.tsx#L1-L86), [apps/web/app/app.dub.co/deeplink/deeplink/domain/...key/page.tsx:45-255](https://github.com/blade47/dub/blob/HEAD/apps/web/app/app.dub.co/deeplink/deeplink/domain/...key/page.tsx#L45-L255)

### Custom Domain Routing and Placeholder Fallbacks

When visitors access a custom domain root, the application renders a specialized welcome page (`CustomDomainPage`) configured with custom metadata derived from the domain name parameter. The page caches responses indefinitely via `revalidate = false` and serves static parameters via `generateStaticParams()`.

```typescript
export const revalidate = false; // cache indefinitely

export async function generateMetadata(props: {
  params: Promise<{ domain: string }>;
}) {
  const params = await props.params;
  const title = `${params.domain.toUpperCase()} - A Dub Custom Domain`;
  const description = `${params.domain.toUpperCase()} is a custom domain on Dub - the modern link attribution platform for short links, conversion tracking, and affiliate programs.`;

  return constructMetadata({
    title,
    description,
  });
}

export function generateStaticParams() {
  return [];
}
```

Sources: [apps/web/app/domain/page.tsx:11-28](https://github.com/blade47/dub/blob/HEAD/apps/web/app/domain/page.tsx#L11-L28)

The custom domain layout embeds a feature showcase section (`FeaturesSection`) that dynamically formats feature cards with marketing utilities. Each card generates tracking-enabled hyperlinks via `createHref` utilizing UTM parameters (`utm_source: "Custom Domain"`, `utm_medium: "Welcome Page"`).

| Feature Card Title | Description Summary | Link Action / Destination |
| :--- | :--- | :--- |
| **Stand out with custom domains** | Create branded short links with your own domain and improve click-through rates. | Learn more (`/help/article/how-to-add-custom-domain`) |
| **Branded QR codes** | Free QR codes for every short link with custom logo support. | Try the demo (`/tools/qr-code`) |
| **Analytics that matter** | Geolocation, device, browser, and referrer metrics. | Explore analytics (`/help/article/dub-analytics`) |
| **Advanced link features** | Custom previews, device/geo targeting, link cloaking, and password protection. | Learn more (`/help/article/how-to-create-link`) |
| **Collaborate with your team** | Teammate collaboration and SAML SSO (Okta, Google, Azure AD). | Learn more (`/help/article/how-to-invite-teammates`) |

Sources: [apps/web/app/domain/page.tsx:30-84](https://github.com/blade47/dub/blob/HEAD/apps/web/app/domain/page.tsx#L30-L84), [apps/web/ui/placeholders/features-section.tsx:37-116](https://github.com/blade47/dub/blob/HEAD/apps/web/ui/placeholders/features-section.tsx#L37-L116)

> [!NOTE]
> The `FeaturesSection` client component extracts the active domain using Next.js `useParams()` and wraps feature descriptions in a Markdown renderer that intercepts anchor tags to open them in external browser contexts.

Sources: [apps/web/ui/placeholders/features-section.tsx:15-20](https://github.com/blade47/dub/blob/HEAD/apps/web/ui/placeholders/features-section.tsx#L15-L20), [apps/web/ui/placeholders/features-section.tsx:161-176](https://github.com/blade47/dub/blob/HEAD/apps/web/ui/placeholders/features-section.tsx#L161-L176)

### Deep Link Resolution Mechanisms

The deep linking subsystem (`DeepLinkPreviewPage`) processes incoming requests across arbitrary domains and optional key parameters (`...key`), orchestrating mobile platform detection and database validation.

```typescript
export default async function DeepLinkPreviewPage(props: {
  params: Promise<{ domain: string; key?: string[] }>;
}) {
  const params = await props.params;
  const domain = params.domain;
  const key = params.key ? decodeURIComponent(params.key.join("/")) : "_root";

  // Detect language from Accept-Language header
  const headersList = await headers();
  const acceptLanguage = headersList.get("accept-language");
  const language = getLanguage(acceptLanguage);
  const t = getTranslations(language);

  const ua = userAgent({ headers: headersList });
  const platform: "ios" | "android" =
    ua.os?.name === "Android" ? "android" : "ios";

  // Encode the key for case-sensitive domains before querying
  const encodedKey = encodeKeyIfCaseSensitive({
    domain,
    key,
  });

  let link = await prisma.link.findUnique({
    where: {
      domain_key: {
        domain,
        key: encodedKey,
      },
    },
    select: {
      domain: true,
      key: true,
      shortLink: true,
      url: true,
      ios: true,
      android: true,
      shortDomain: {
        select: {
          appleAppSiteAssociation: true,
          assetLinks: true,
          deepviewData: true,
        },
      },
    },
  });

  // if the link doesn't exist, we redirect to the root domain link
  if (!link) {
    redirect(`https://${domain}`);
  }
...
```

Sources: [apps/web/app/app.dub.co/deeplink/deeplink/domain/...key/page.tsx:45-95](https://github.com/blade47/dub/blob/HEAD/apps/web/app/app.dub.co/deeplink/deeplink/domain/...key/page.tsx#L45-L95)

Once the database record is retrieved, platform-specific association checks determine whether to render the deep link preview UI or perform an immediate redirection.

```typescript
  const { appleAppSiteAssociation, assetLinks, deepviewData } =
    link.shortDomain;

  // if the domain isn't set up for deep linking on the user's platform, skip
  // the preview and forward to the platform-specific URL (or the canonical URL)
  if (platform === "android") {
    if (!assetLinks || !deepviewData) {
      redirect(link.android ?? link.url);
    }
  } else {
    if (!appleAppSiteAssociation || !deepviewData) {
      redirect(link.ios ?? link.url);
    }
  }

  const deepViewData = parseDeepViewData(deepviewData);

  // decode the link if the domain is case sensitive
  link = decodeLinkIfCaseSensitive(link);

  // This should never happen
  if (!link) {
    redirect(`https://${domain}`);
  }
```

Sources: [apps/web/app/app.dub.co/deeplink/deeplink/domain/...key/page.tsx:97-120](https://github.com/blade47/dub/blob/HEAD/apps/web/app/app.dub.co/deeplink/deeplink/domain/...key/page.tsx#L97-L120)

> [!WARNING]
> If a short link record cannot be found in the database during deep link resolution, the handler immediately terminates execution and issues an HTTP redirect back to the root domain (`https://${domain}`).

Sources: [apps/web/app/app.dub.co/deeplink/deeplink/domain/...key/page.tsx:92-95](https://github.com/blade47/dub/blob/HEAD/apps/web/app/app.dub.co/deeplink/deeplink/domain/...key/page.tsx#L92-L95)

## Workspace Onboarding and Plan Tiers

### Overview

Account registration and workspace setup begin through the authentication marketing registration page (`RegisterPage`), which wraps `RegisterPageClient` inside an `AuthLayout` configured with `showTerms="app"`.

Sources: [apps/web/app/app.dub.co/auth-marketing/register/page.tsx:10-16](https://github.com/blade47/dub/blob/HEAD/apps/web/app/app.dub.co/auth-marketing/register/page.tsx#L10-L16)

Once registered, users enter the multi-step onboarding journey governed by the layout component in `apps/web/app/app.dub.co/onboarding/onboarding/steps/layout.tsx`. This layout renders an absolute background featuring a 60px-cell grid (`Grid`) and an `AuroraGradient`, centered with a `Wordmark` pointing to `https://dub.co/home`, and a mobile `SignedInHint` component.

Sources: [apps/web/app/app.dub.co/onboarding/onboarding/steps/layout.tsx:8-53](https://github.com/blade47/dub/blob/HEAD/apps/web/app/app.dub.co/onboarding/onboarding/steps/layout.tsx#L8-L53)

The onboarding flow progresses through discrete steps:
1. **Welcome (`/welcome`)**: Invokes `TrackSignup` and renders `AccountTypeSelector` inside `StepPage` with test ID `testIds.onboarding.stepWelcome` and a maximum width of `640px`.
Sources: [apps/web/app/app.dub.co/onboarding/onboarding/steps/welcome/page.tsx:6-20](https://github.com/blade47/dub/blob/HEAD/apps/web/app/app.dub.co/onboarding/onboarding/steps/welcome/page.tsx#L6-L20)
2. **Products (`/products`)**: Renders `ProductSelector` within `StepPage` (`testIds.onboarding.stepProducts`), asking users what they want to do with Dub across an unconstrained width (`max-w-none`).
Sources: [apps/web/app/app.dub.co/onboarding/onboarding/steps/products/page.tsx:5-16](https://github.com/blade47/dub/blob/HEAD/apps/web/app/app.dub.co/onboarding/onboarding/steps/products/page.tsx#L5-L16)
3. **Plan (`/plan`)**: Dynamically adjusts its title and description based on the active product retrieved via `useOnboardingProduct()`. It provisions plan choices via `PlanSelector` and offers an enterprise link, a free plan button, and a product-specific pricing comparison link.
Sources: [apps/web/app/app.dub.co/onboarding/onboarding/steps/plan/page.tsx:13-78](https://github.com/blade47/dub/blob/HEAD/apps/web/app/app.dub.co/onboarding/onboarding/steps/plan/page.tsx#L13-L78)
4. **Success (`/success`)**: Concludes onboarding by rendering workspace settings shortcuts, an optional Slack support invitation flow via `SlackSupportInviteModal`, and navigational links to team management, the help center, documentation, and support chat.
Sources: [apps/web/app/app.dub.co/onboarding/onboarding/steps/success/page-client.tsx:273-382](https://github.com/blade47/dub/blob/HEAD/apps/web/app/app.dub.co/onboarding/onboarding/steps/success/page-client.tsx#L273-L382)

> [!NOTE]
> During the onboarding plan step (`/plan`), if the selected product is set to `"links"`, the UI renders a `LaterButton` that allows users to defer plan selection and jump straight to the `"success"` step with the free tier.

Sources: [apps/web/app/app.dub.co/onboarding/onboarding/steps/plan/page.tsx:58-66](https://github.com/blade47/dub/blob/HEAD/apps/web/app/app.dub.co/onboarding/onboarding/steps/plan/page.tsx#L58-L66)

### Feature Tier Provisioning

Feature availability across subscription tiers is defined in `PRICING_PLAN_COMPARE_FEATURES`. The structure organizes limits, boolean checks, and text renderers across categories such as Links, Partners, Analytics, Domains, API, Workspace, and Support.

| Category | Feature Item | Free Tier Access | Pro Tier Access | Business Tier Access | Advanced Tier Access | Enterprise Tier Access |
| :--- | :--- | :--- | :--- | :--- | :--- | :--- |
| **Links** | Folders | Restricted (`false`) | Enabled (`true`) | Enabled (`true`) | Enabled (`true`) | Enabled (`true`) |
| **Links** | Custom link previews | Restricted (`false`) | Enabled (`true`) | Enabled (`true`) | Enabled (`true`) | Enabled (`true`) |
| **Links** | Deep links | Restricted (`false`) | Enabled (`true`) | Enabled (`true`) | Enabled (`true`) | Enabled (`true`) |
| **Links** | Link cloaking | Restricted (`false`) | Enabled (`true`) | Enabled (`true`) | Enabled (`true`) | Enabled (`true`) |
| **Links** | Link expiration | Restricted (`false`) | Enabled (`true`) | Enabled (`true`) | Enabled (`true`) | Enabled (`true`) |
| **Links** | Password protection | Restricted (`false`) | Enabled (`true`) | Enabled (`true`) | Enabled (`true`) | Enabled (`true`) |
| **Links** | Device targeting | Restricted (`false`) | Enabled (`true`) | Enabled (`true`) | Enabled (`true`) | Enabled (`true`) |
| **Links** | Geo targeting | Restricted (`false`) | Enabled (`true`) | Enabled (`true`) | Enabled (`true`) | Enabled (`true`) |
| **Links** | A/B testing | Restricted (`false`) | Restricted (`false`) | Enabled (`true`) | Enabled (`true`) | Enabled (`true`) |
| **Partners** | Automated global payouts | Restricted (`false`) | Restricted (`false`) | Enabled (`true`) | Enabled (`true`) | Enabled (`true`) |
| **Partners** | Tax compliance | Restricted (`false`) | Restricted (`false`) | Enabled (`true`) | Enabled (`true`) | Enabled (`true`) |
| **Partners** | Dual-sided incentives | Restricted (`false`) | Restricted (`false`) | Enabled (`true`) | Enabled (`true`) | Enabled (`true`) |
| **Partners** | AI landing page generator | Restricted (`false`) | Restricted (`false`) | Enabled (`true`) | Enabled (`true`) | Enabled (`true`) |
| **Partners** | Embedded referral dashboard | Restricted (`false`) | Restricted (`false`) | Restricted (`false`) | Enabled (`true`) | Enabled (`true`) |
| **Partners** | Messaging center | Restricted (`false`) | Restricted (`false`) | Restricted (`false`) | Enabled (`true`) | Enabled (`true`) |
| **Partners** | Email campaigns | Restricted (`false`) | Restricted (`false`) | Restricted (`false`) | Enabled (`true`) | Enabled (`true`) |
| **Partners** | Partner network access | Restricted (`false`) | Restricted (`false`) | Restricted (`false`) | Restricted (`false`) | Enabled (`true`) |
| **Analytics** | Conversion tracking | Restricted (`false`) | Restricted (`false`) | Enabled (`true`) | Enabled (`true`) | Enabled (`true`) |
| **Analytics** | Customer insights | Restricted (`false`) | Restricted (`false`) | Enabled (`true`) | Enabled (`true`) | Enabled (`true`) |
| **Analytics** | Real-time events stream | Restricted (`false`) | Restricted (`false`) | Enabled (`true`) | Enabled (`true`) | Enabled (`true`) |
| **Domains** | Free `.link` domain | Restricted (`false`) | Enabled (`true`) | Enabled (`true`) | Enabled (`true`) | Enabled (`true`) |
| **API** | Event webhooks | Restricted (`false`) | Restricted (`false`) | Enabled (`true`) | Enabled (`true`) | Enabled (`true`) |
| **Workspace** | Role-based access control | Restricted (`false`) | Restricted (`false`) | Enabled (`true`) | Enabled (`true`) | Enabled (`true`) |
| **Workspace** | SAML/SSO | Restricted (`false`) | Restricted (`false`) | Restricted (`false`) | Restricted (`false`) | Enabled (`true`) |
| **Workspace** | Audit logs | Restricted (`false`) | Restricted (`false`) | Restricted (`false`) | Restricted (`false`) | Enabled (`true`) |
| **Support** | Dedicated success manager | Restricted (`false`) | Restricted (`false`) | Restricted (`false`) | Restricted (`false`) | Enabled (`true`) |

Sources: [packages/utils/src/constants/pricing/pricing-plan-compare-features.tsx:11-612](https://github.com/blade47/dub/blob/HEAD/packages/utils/src/constants/pricing/pricing-plan-compare-features.tsx#L11-L612)

## Partner Programs and Embeddable Systems

### Overview

Enterprise partner program management and embeddable client systems provide infrastructure for scaling referral networks. The Dub platform coordinates partner analytics, creation flows, and browser-side embedding across distributed web properties.

Sources: [apps/web/app/app.dub.co/dashboard/slug/ee/program/page.tsx:5-20](https://github.com/blade47/dub/blob/HEAD/apps/web/app/app.dub.co/dashboard/slug/ee/program/page.tsx#L5-L20), [apps/web/app/ee/app.dub.co/embed/referrals/quickstart.tsx:22-209](https://github.com/blade47/dub/blob/HEAD/apps/web/app/ee/app.dub.co/embed/referrals/quickstart.tsx#L22-L209)

### Embed Client Integration

The embed client initializes global browser hooks by attaching a `Dub` interface to the `window` object when executed in browser environments. This system powers embedded partner portals such as quickstart links, resource management, and payout connections.

```typescript
import { init } from "./core";
import { DubEmbed } from "./types";

declare global {
  interface Window {
    Dub: DubEmbed;
  }
}

if (typeof window !== "undefined") {
  window.Dub = (window.Dub || {}) as DubEmbed;
  window.Dub.init = init;
}
```

Sources: [packages/embeds/core/src/embed.ts:1-14](https://github.com/blade47/dub/blob/HEAD/packages/embeds/core/src/embed.ts#L1-L14)

### Referral Quickstart Actions

The referral quickstart component structures partner onboarding flows into discrete actionable blocks including link sharing, resource downloads, and payout configurations.

| Action Item | Target Tab / Destination | Prerequisite Condition | CTA State / Behavior |
| :--- | :--- | :--- | :--- |
| **Share your link** | `"Links"` tab | `links.length > 0` | Copies constructed partner link or navigates to link creation. |
| **Program resources** | `"Resources"` tab | `hasResources: boolean` | Disables button if no resource assets are attached (`!hasResources`). |
| **Browse the FAQ** | `"FAQ"` tab | `programEmbedData?.hideEarnings` | Opens FAQ accordion list when earnings are hidden. |
| **Receive earnings** | `"Settings"` tab or external URL | `earnings.upcoming === 0 && earnings.paid === 0` | Routes to Tremendous payout settings or external portal based on country support and default method. |

Sources: [apps/web/app/ee/app.dub.co/embed/referrals/quickstart.tsx:22-160](https://github.com/blade47/dub/blob/HEAD/apps/web/app/ee/app.dub.co/embed/referrals/quickstart.tsx#L22-L160)

> [!NOTE]
> The Payout configuration step dynamically checks `TREMENDOUS_SUPPORTED_COUNTRIES` against the partner's registered country profile to determine if internal payout settings should render or if redirection to external partners is required.

Sources: [apps/web/app/ee/app.dub.co/embed/referrals/quickstart.tsx:138-154](https://github.com/blade47/dub/blob/HEAD/apps/web/app/ee/app.dub.co/embed/referrals/quickstart.tsx#L138-L154)

## Ecosystem Integrations and Extensibility

### Ecosystem Integrations and Extensibility

Third-party application integration, CRM connectors, and embedded marketplace layouts extend Dub's core link management capabilities into broader enterprise ecosystems. The platform coordinates integrations through dedicated packages, client configuration parameters, and layout structures.

Sources: [packages/hubspot-app/hsproject.json:1-5](https://github.com/blade47/dub/blob/HEAD/packages/hubspot-app/hsproject.json#L1-L5), [packages/stripe-app/src/utils/constants.ts:1-6](https://github.com/blade47/dub/blob/HEAD/packages/stripe-app/src/utils/constants.ts#L1-L6), [apps/web/app/app.dub.co/marketplace/layout.tsx:1-19](https://github.com/blade47/dub/blob/HEAD/apps/web/app/app.dub.co/marketplace/layout.tsx#L1-L19)

### CRM and Third-Party Connectors

Dub packages integrations with external platforms such as HubSpot and Stripe, providing standardized identifiers and environment properties for application exchange. The HubSpot project configuration establishes project names and platform execution versions, while Stripe application constants define client identifiers and host endpoints.

```json
{
  "name": "Dub",
  "srcDir": "src",
  "platformVersion": "2025.2"
}
```

Sources: [packages/hubspot-app/hsproject.json:1-5](https://github.com/blade47/dub/blob/HEAD/packages/hubspot-app/hsproject.json#L1-L5), [packages/stripe-app/src/utils/constants.ts:1-6](https://github.com/blade47/dub/blob/HEAD/packages/stripe-app/src/utils/constants.ts#L1-L6)

| Integration Constant | Value / Identifier | Target Purpose |
| :--- | :--- | :--- |
| **`DUB_CLIENT_ID`** | `"dub_app_517290377fe6b4dfcc8726a7061ba9b6da1c4d7d7d75f77a"` | OAuth and application authentication for Stripe app integration. |
| **`DUB_HOST`** | `"https://app.dub.co"` | Primary web application host URL for redirect and routing flows. |
| **`DUB_API_HOST`** | `"https://api.dub.co"` | Base API routing endpoint for programmatic third-party requests. |
| **`platformVersion`** | `"2025.2"` | HubSpot project execution environment specification. |

Sources: [packages/hubspot-app/hsproject.json:1-5](https://github.com/blade47/dub/blob/HEAD/packages/hubspot-app/hsproject.json#L1-L5), [packages/stripe-app/src/utils/constants.ts:1-6](https://github.com/blade47/dub/blob/HEAD/packages/stripe-app/src/utils/constants.ts#L1-L6)

### Embedded Marketplace Navigation

The external marketplace layout renders responsive integration directories with custom grid lines, header components, and integrated footers. Navigation resources organize documentation, company profiles, and updates into categorized resource columns.

```typescript
const COLUMNS = [
  {
    heading: "Help and Support",
    titles: ["Docs", "Help Center", "Contact"],
  },
  {
    heading: "Company",
    titles: ["About", "Careers", "Dub Brand"],
  },
  {
    heading: "Updates",
    titles: ["Blog", "Changelog"],
  },
];
```

Sources: [apps/web/app/app.dub.co/marketplace/layout.tsx:1-34](https://github.com/blade47/dub/blob/HEAD/apps/web/app/app.dub.co/marketplace/layout.tsx#L1-L34), [packages/ui/src/nav/content/resources-content.tsx:10-23](https://github.com/blade47/dub/blob/HEAD/packages/ui/src/nav/content/resources-content.tsx#L10-L23)

> [!TIP]
> The marketplace external layout includes `MarketplaceExternalGridLines` which draws fixed vertical border dividers constrained to a maximum container width of `max-w-screen-xl` with gradient masks starting at 96px.

Sources: [apps/web/app/app.dub.co/marketplace/layout.tsx:21-33](https://github.com/blade47/dub/blob/HEAD/apps/web/app/app.dub.co/marketplace/layout.tsx#L21-L33)

## Related

- [Quick Start](https://www.doc0.dev/docs/934e554a-e6a1-476f-bb2f-23e62d86c3fd/technical/getting-started/quick-start)
- [Project Structure](https://www.doc0.dev/docs/934e554a-e6a1-476f-bb2f-23e62d86c3fd/technical/getting-started/project-structure)
- [Routing and Multitenancy](https://www.doc0.dev/docs/934e554a-e6a1-476f-bb2f-23e62d86c3fd/technical/core-architecture/routing-and-multitenancy)


## Sitemap

See the full [sitemap](https://www.doc0.dev/docs/934e554a-e6a1-476f-bb2f-23e62d86c3fd/llms.txt) for all pages in this wiki.
