Relevant source files
The following files were used as context for generating this wiki page:
- apps/web/app/ee/admin.dub.co/dashboard/page.tsx
- apps/web/app/ee/admin.dub.co/dashboard/components/impersonate-user.tsx
- apps/web/app/ee/api/admin/impersonate/route.ts
- apps/web/app/ee/admin.dub.co/dashboard/partners/trusted/page.tsx
- apps/web/app/ee/admin.dub.co/dashboard/domains/page.tsx
- apps/web/ui/domains/domain-card.tsx
- apps/web/app/app.dub.co/dashboard/slug/ee/settings/domains/page-client.tsx
- apps/web/app/ee/admin.dub.co/dashboard/partners/network/page.tsx
- apps/web/app/ee/admin.dub.co/dashboard/programs/page.tsx
- apps/web/app/ee/admin.dub.co/dashboard/links/page.tsx
- apps/web/lib/auth/admin-access-guard.ts
- apps/web/app/ee/admin.dub.co/dashboard/partners/page.tsx
- apps/web/app/ee/admin.dub.co/dashboard/layout-nav-client.tsx
- apps/web/lib/auth/admin-impersonation.ts
- apps/web/lib/middleware/admin.ts
- apps/web/app/ee/admin.dub.co/dashboard/partners/network/network-partner-application-sheet.tsx
- apps/web/app/ee/admin.dub.co/dashboard/analytics/page.tsx
- apps/web/app/ee/api/admin/links/route.ts
- apps/web/app/ee/api/admin/partners/trusted/route.ts
- apps/web/app/ee/admin.dub.co/dashboard/events/page.tsx
- apps/web/app/ee/admin.dub.co/dashboard/links/links-nav-tabs.tsx
- apps/web/app/ee/admin.dub.co/dashboard/layout.tsx
- apps/web/app/app.dub.co/dashboard/slug/ee/settings/domains/page.tsx
- apps/web/app/app.dub.co/dashboard/slug/ee/settings/domains/default/page-client.tsx
- apps/web/app/ee/admin.dub.co/dashboard/links/components/disable-restore-workspace.tsx
- apps/web/lib/auth/admin.ts
- apps/web/app/app.dub.co/dashboard/slug/ee/settings/domains/default/page.tsx
- apps/web/app/ee/admin.dub.co/dashboard/links/list/page.tsx
- apps/web/app/domain/browser-graphic.tsx
- apps/web/app/ee/api/admin/fraud-alerts/route.ts
Overview
The admin dashboard provides a centralized management and moderation portal for Dub administrators and enterprise staff. It operates as an internal interface hosted under the admin.dub.co domain, restricted to authorized users belonging to the core Dub workspace. By integrating role-based access guards, session impersonation tools, global link and workspace controls, partner oversight workflows, and custom registrar management tools, the dashboard equips operators with the capabilities needed to supervise platform traffic, review affiliate applications, and handle security incidents.
Sources: apps/web/lib/auth/admin.ts:22-39, apps/web/lib/middleware/admin.ts:8-37
Admin Authentication and Role Guards
Role Verification and Workspace Validation
Dub implements a multi-layered security model to verify internal administrative roles, enforce route guards across edge middleware and API endpoints, and filter UI navigation tabs based on user-specific access rules.
The administrative access architecture relies on membership within the primary Dub workspace (DUB_WORKSPACE_ID). The function getDubAdminRole queries prisma.projectUsers using the user ID and the fixed workspace identifier to retrieve the user's assigned WorkspaceRole.
export const getDubAdminRole = async (userId: string) => {
const response = await prisma.projectUsers.findUnique({
where: {
userId_projectId: {
userId,
projectId: DUB_WORKSPACE_ID,
},
},
select: {
role: true,
},
});
if (!response) {
return null;
}
return response.role;
};Sources: apps/web/lib/auth/admin.ts:22-39
API routes intended for administrative use are wrapped with the withAdmin higher-order function. This handler enforces a strict sequence of checks before executing the underlying controller logic:
- Validates that an active session and user object exist, returning a
401 Unauthorizedresponse otherwise. - Resolves the user's admin role via
getDubAdminRole; if no role is found, it returns a401 Unauthorizedresponse. - If
requiredRolesare specified, it verifies that the user's role is included in the permitted list, returning a403 Forbiddenresponse if validation fails. - Validates API path access using
canAccessAdminApiPath.
export const withAdmin =
(
handler: WithAdminHandler,
{ requiredRoles = [] }: { requiredRoles?: WorkspaceRole[] } = {},
) =>
async (
req: Request,
{ params: initialParams }: { params: Promise<Record<string, string>> },
) => {
const params = (await initialParams) || {};
const session = await getSession();
if (!session?.user) {
return new Response("Unauthorized: Login required.", { status: 401 });
}
const adminRole = await getDubAdminRole(session.user.id);
if (!adminRole) {
return new Response("Unauthorized: Not an admin.", { status: 401 });
}
if (requiredRoles.length > 0 && !requiredRoles.includes(adminRole)) {
return new Response(
`Unauthorized: Missing required admin role(s): ${requiredRoles.join(", ")}.`,
{ status: 403 },
);
}
if (
!canAccessAdminApiPath({
userId: session.user.id,
pathname: new URL(req.url).pathname,
})
) {
return new Response("Unauthorized: You don't have access to this page.", {
status: 403,
});
}
Sources: apps/web/lib/auth/admin.ts:41-78
Important
Administrative API endpoints check both workspace project membership and path-specific blocklists. A valid workspace role alone does not grant access to restricted API paths if the user's identifier appears in the admin access blocklist.
Edge Middleware Guards
Incoming requests to the admin.dub.co domain are intercepted by AdminMiddleware. The middleware inspects the user token, checks project membership against DUB_WORKSPACE_ID using prismaEdge.projectUsers.findUnique, and enforces navigation rules before rewriting or redirecting the request.
export async function AdminMiddleware(req: NextRequest) {
const { path } = parse(req);
const user = await getUserViaToken(req);
if (!user && path !== "/login") {
return NextResponse.redirect(new URL("/login", req.url));
} else if (user) {
const isAdminUser = await prismaEdge.projectUsers.findUnique({
where: {
userId_projectId: {
userId: user.id,
projectId: DUB_WORKSPACE_ID,
},
},
});
if (!isAdminUser) {
return NextResponse.next(); // throw 404 page
} else if (
path === "/login" ||
!canAccessAdminPath({ userId: user.id, pathname: path })
) {
return NextResponse.redirect(new URL("/", req.url));
}
}
return NextResponse.rewrite(
new URL(`/admin.dub.co${path === "/" ? "" : path}`, req.url),
);Sources: apps/web/lib/middleware/admin.ts:8-37
Access Blocklists and Restricted Paths
Certain administrative user IDs can be restricted from accessing specific sensitive dashboard sections and API namespaces through ADMIN_ACCESS_BLOCKLIST.
| Guard Constant | Value / Path Array | Purpose |
|---|---|---|
ADMIN_ACCESS_BLOCKLIST | ["user_1M3YFDDQ97AGTKWQ9NCSRQTYB"] | Identifies user IDs excluded from restricted administrative paths. |
ADMIN_RESTRICTED_PATHS | ["/links", "/revenue", "/domains"] | Dashboard frontend paths blocked for blocklisted users. |
ADMIN_RESTRICTED_API_PATHS | ["/api/admin/links", "/api/admin/workspaces", "/api/admin/revenue", "/api/admin/domains"] | API routes blocked for blocklisted users. |
Sources: apps/web/lib/auth/admin-access-guard.ts:3-14
Path matching is handled by canAccessAdminPath and canAccessAdminApiPath, which evaluate whether a given pathname matches or starts with any entry in the restricted path arrays for blocklisted users.
const matchesPath = (pathname: string, paths: string[]) =>
paths.some((p) => pathname === p || pathname.startsWith(`${p}/`));
export const isAdminAccessRestricted = (userId?: string | null): boolean =>
!!userId && ADMIN_ACCESS_BLOCKLIST.includes(userId);
export const canAccessAdminPath = ({
userId,
pathname,
}: {
userId?: string | null;
pathname: string;
}): boolean =>
!isAdminAccessRestricted(userId) ||
!matchesPath(pathname, ADMIN_RESTRICTED_PATHS);
export const canAccessAdminApiPath = ({
userId,
pathname,
}: {
userId?: string | null;
pathname: string;
}): boolean =>
!isAdminAccessRestricted(userId) ||
!matchesPath(pathname, ADMIN_RESTRICTED_API_PATHS);Sources: apps/web/lib/auth/admin-access-guard.ts:16-40
UI Navigation Filtering
The admin dashboard layout client utilizes session state and canAccessAdminPath to dynamically filter navigation tabs rendered in AdminNav. Tabs such as links, revenue, and domains are hidden or omitted for users subject to access restrictions.
const visibleTabs = useMemo(
() =>
status === "loading"
? []
: tabs.filter((tab) =>
canAccessAdminPath({
userId: session?.user?.id,
pathname: tab.href,
}),
),
[status, session?.user?.id],
);Sources: apps/web/app/ee/admin.dub.co/dashboard/layout-nav-client.tsx:57-68
User Impersonation Flow
Identifier Parsing and Query Resolution
The user impersonation system allows administrators to look up accounts by email, workspace slug, custom domain, or Stripe customer ID, view linked projects and partner metrics, and generate secure impersonation links. The client interface handles input parsing, clipboard paste normalization, and user ban actions.
export function ImpersonateUser() {
const [data, setData] = useState<UserInfoProps | null>(null);
const [blockEmailDomain, setBlockEmailDomain] = useState(false);
return (
<div className="flex flex-col space-y-5">
<form
action={async (formData) => {
await fetch("/api/admin/impersonate", {
method: "POST",
body: JSON.stringify({
query: formData.get("query"),
}),
}).then(async (res) => {
if (res.ok) {
setBlockEmailDomain(false);
setData(await res.json());
} else {
const error = await res.text();
toast.error(error);
}
});
}}
>
<Form />
</form>
{data ? (
<form
action={async () => {
const emailDomain = data.email.split("@")[1];
const blockDomainMessage = blockEmailDomain
? ` and block signups from @${emailDomain}`
: "";
if (
!confirm(
`This will ban the user ${data.email} and delete all their workspaces and links${blockDomainMessage}. Are you sure?`,
)
) {
return;
}
await fetch("/api/admin/ban", {
method: "POST",
body: JSON.stringify({
email: data.email,
blockEmailDomain,
}),
}).then(async (res) => {
if (res.ok) {
toast.success("User has been banned");
} else {
const error = await res.text();
toast.error(error);
}
});
}}
>
<UserInfo data={data} />
<label className="mt-4 flex cursor-pointer items-center gap-2 text-sm text-neutral-600">
<input
type="checkbox"
checked={blockEmailDomain}
onChange={(e) => setBlockEmailDomain(e.target.checked)}
className="rounded border-neutral-300 text-neutral-900 focus:ring-neutral-500"
/>
Also block signups from @{data.email.split("@")[1]}
</label>
<div className="mt-4">
<BanButton />
</div>
</form>
) : (
<UserInfoSkeleton />
)}
</div>
);
}Sources: apps/web/app/ee/admin.dub.co/dashboard/components/impersonate-user.tsx:10-86
When an administrator inputs a search query into the form, clipboard paste events are intercepted to clean prefixes such as mailto: and extract Stripe customer identifiers matching cus_[a-zA-Z0-9]+. The backend API processes this input through parseImpersonateQuery to categorize the target into one of four specific identifier types.
| Identifier Type | Matching Pattern / Condition | Resolution Rule |
|---|---|---|
email | Contains @ | Validated against emailSchema using Zod. |
stripeCustomerId | Starts with cus_ or contains stripe.com | Matched using STRIPE_CUSTOMER_ID_REGEX. |
slug | Hostname matches app domain with a valid path segment, or raw input matches validSlugRegex | Lowercased and checked against slug regex. |
domain | Normalized input matches validDomainRegex | Normalized via normalizeDomainInput. |
Sources: apps/web/app/ee/api/admin/impersonate/route.ts:105-180, apps/web/app/ee/admin.dub.co/dashboard/components/impersonate-user.tsx:104-118
Note
If a query string contains a URL pointing to the primary application hostname, the parser extracts the first path segment as a workspace slug, provided it satisfies validSlugRegex. Otherwise, it falls back to domain or slug validation on the raw string.
Usage Metrics and Serialization
Once a user is located, their associated projects and partner configurations are serialized. Projects are selected with fields including plan tiers, trial expiration dates, partner usage statistics, total clicks, total links, and associated programs. If a user belongs to two or fewer projects, the system queries the last 30 days of workspace statistics using getLast30DayWorkspaceStats. Additionally, program commissions are grouped and aggregated by programId.
const userSelect = {
email: true,
projects: {
select: {
project: {
select: {
id: true,
name: true,
slug: true,
plan: true,
planPeriod: true,
trialEndsAt: true,
defaultProgramId: true,
partnersUsage: true,
totalClicks: true,
totalLinks: true,
programs: {
select: {
id: true,
slug: true,
url: true,
},
},
},
},
},
orderBy: {
project: {
totalClicks: "desc",
},
},
},
partners: {
select: {
partner: {
select: {
programs: {
select: {
program: {
select: {
id: true,
name: true,
slug: true,
},
},
status: true,
totalClicks: true,
totalLeads: true,
totalConversions: true,
totalSaleAmount: true,
totalCommissions: true,
},
orderBy: {
totalCommissions: "desc",
},
},
},
},
},
},
} satisfies Prisma.UserSelect;Sources: apps/web/app/ee/api/admin/impersonate/route.ts:19-79, apps/web/app/ee/api/admin/impersonate/route.ts:227-245
Session Tracking and Impersonation Tokens
Tracking of active administrative impersonation sessions is managed through an in-memory tracking structure in admin-impersonation.ts. When an administrator initiates an impersonation session, the target user's email is marked as a pending impersonation event.
// Tracks emails signing in via admin impersonation links. Populated in
// CustomPrismaAdapter.useVerificationToken before the token is deleted.
const pendingAdminImpersonations = new Set<string>();
export const markAdminImpersonation = (email: string) => {
pendingAdminImpersonations.add(email.toLowerCase());
};
export const consumeAdminImpersonation = (email: string) => {
const isAdminImpersonation = pendingAdminImpersonations.has(
email.toLowerCase(),
);
if (isAdminImpersonation) {
pendingAdminImpersonations.delete(email.toLowerCase());
}
return isAdminImpersonation;
};Sources: apps/web/lib/auth/admin-impersonation.ts:1-19
Caution
The pendingAdminImpersonations set tracks emails signing in via admin impersonation links and is populated within CustomPrismaAdapter.useVerificationToken immediately before the verification token is consumed and deleted.
Link and Workspace Moderation
Link Search and Filtering
Administrators can moderate platform links through administrative search and filtering endpoints and the links dashboard. The backend API handles queries with sorting and pagination.
// GET /api/admin/links
export const GET = withAdmin(async ({ searchParams }) => {
const {
domain,
search,
sort = "createdAt",
page,
} = searchParams as {
domain?: string;
search?: string;
sort?: "createdAt" | "clicks" | "lastClicked";
page?: string;
};
Sources: apps/web/app/ee/api/admin/links/route.ts:7-20
| Parameter | Type / Options | Description |
|---|---|---|
domain | string | Filter links by specific custom domain. |
search | string | Search query for short links or destination URLs. |
sort | "createdAt" | "clicks" | "lastClicked" | Ordering field for query results (default: createdAt). |
page | string | Pagination offset index (100 items per page). |
Sources: apps/web/app/ee/api/admin/links/route.ts:9-19, apps/web/app/ee/api/admin/links/route.ts:71-77
Note
When no search query is provided, the API automatically restricts queries to domains defined in DUB_DOMAINS_ARRAY created within the last 30 days, while excluding legal user accounts (LEGAL_USER_ID) or unassigned links.
Sources: apps/web/app/ee/api/admin/links/route.ts:21-40
If a search query begins with https://, the query matches the shortLink field precisely. Otherwise, it performs an OR-match searching partial substrings across both shortLink and destination url fields.
Sources: apps/web/app/ee/api/admin/links/route.ts:41-55
Workspace Disabling and Restoration
Administrative moderation includes tools to disable or restore all links associated with a workspace slug. The interface requires entering a workspace slug (prefixed with app.dub.co/) and executing actions via POST requests to workspace moderation endpoints.
const handleAction = async (action: "disable" | "restore", slug: string) => {
const message =
action === "disable"
? `Are you sure you want to disable all links for workspace "${slug}"? This will also downgrade owners to billing and members to viewer, and notify workspace owners by email.`
: `Are you sure you want to restore all links for workspace "${slug}"? This will also revert billing users to owner and viewers to member.`;
if (!window.confirm(message)) return;
setPending(action);
try {
const res = await fetch(`/api/admin/workspaces/${action}`, {
method: "POST",
body: JSON.stringify({ slug }),
});
if (res.ok) {
toast.success(
action === "disable"
? "Workspace links disabled"
: "Workspace links restored",
);
} else {
const error = await res.text();
toast.error(error || "Something went wrong. Please try again.");
}
} catch {
toast.error("Network error. Please check your connection and try again.");
} finally {
setPending(null);
}
};Sources: apps/web/app/ee/admin.dub.co/dashboard/links/components/disable-restore-workspace.tsx:12-42, apps/web/app/ee/admin.dub.co/dashboard/links/page.tsx:12-20
Caution
Disabling workspace links automatically downgrades owners to billing and members to viewer roles, and dispatches email notifications to workspace owners. Restoring workspace links reverses these role changes, promoting billing users back to owners and viewers back to members.
Sources: apps/web/app/ee/admin.dub.co/dashboard/links/page.tsx:13-18, apps/web/app/ee/admin.dub.co/dashboard/links/components/disable-restore-workspace.tsx:12-17
Partner Network Oversight
Network Partner Applications and Metadata
Administrators review incoming partner applications through the network oversight dashboard at /partners/network. The application listing supports filtering by network status and country, and dynamically selects date columns based on the active status query parameter.
| Status Value | Date Column Identifier | Header Label |
|---|---|---|
submitted | submittedAt | Submitted |
approved | reviewedAt | Approved |
rejected | reviewedAt | Rejected |
| Other/Default | createdAt | Joined |
Sources: apps/web/app/ee/admin.dub.co/dashboard/partners/network/page.tsx:44-66
The application detail sheet provides tabs for inspecting profile metadata, associated affiliate programs, and duplicate account flags. Duplicate partner accounts are automatically flagged when applicants share matching email addresses or profile details.
return (
<div>
<h3 className="text-content-emphasis text-sm font-semibold">
Duplicate partner accounts
</h3>
<p className="mt-1 text-sm text-neutral-500">
These accounts likely match this applicant by email or profile details.
</p>Sources: apps/web/app/ee/admin.dub.co/dashboard/partners/network/network-partner-application-sheet.tsx:495-502, apps/web/app/ee/admin.dub.co/dashboard/partners/network/network-partner-application-sheet.tsx:395-442
Warning
Administrators cannot approve a partner whose current network status is already approved or trusted.
Trusted Partner Management
The trusted partners interface allows administrators with the owner role to promote partners to trusted status or revoke their trusted badge. Partners can be added by their unique identifier (prefixed with pn_) or email address via /api/admin/partners/trusted.
// POST /api/admin/partners/trusted
export const POST = withAdmin(
async ({ req }) => {
const { partnerIdOrEmail } = z
.object({
partnerIdOrEmail: z.string().trim().min(1),
})
.parse(await req.json());
if (
!partnerIdOrEmail.startsWith("pn_") &&
!partnerIdOrEmail.includes("@")
) {
return new Response("Invalid partner ID or email.", { status: 400 });
}
Sources: apps/web/app/ee/api/admin/partners/trusted/route.ts:49-64, apps/web/app/ee/admin.dub.co/dashboard/partners/trusted/page.tsx:105-129
Note
Every status transition updates the partner's change history log (changeHistoryLog) with audit metadata recording the field change from its previous state to either trusted or approved.
Sources: apps/web/app/ee/api/admin/partners/trusted/route.ts:87-97, apps/web/app/ee/api/admin/partners/trusted/route.ts:147-156
Program and Operational Tools
Affiliate Program Management and Partner Account Deletions
Administrators manage affiliate programs directly from the admin dashboard, including listing marketplace programs, updating categories and descriptions via dedicated modals, and reordering display ranks with drag-and-drop controls. Programs can be added via POST /api/admin/programs by providing a program slug, or removed permanently via DELETE /api/admin/programs/[id], which deletes associated commissions, payouts, rewards, discounts, links, customers, partner groups, and enrollments.
<AddProgramModal
showModal={showAddProgramModal}
setShowModal={setShowAddProgramModal}
programSlug={newProgramSlug}
setProgramSlug={setNewProgramSlug}
isLoading={isAddingProgram}
onAdd={async () => {
if (!newProgramSlug.trim()) return;
setIsAddingProgram(true);
const res = await fetch("/api/admin/programs", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
programSlug: newProgramSlug.trim(),
}),
});
if (!res.ok) {
setIsAddingProgram(false);
toast.error((await res.text()) || "Failed to add program.");
return;
}
await mutate();
setIsAddingProgram(false);
setShowAddProgramModal(false);
setNewProgramSlug("");
toast.success("Program added to marketplace.");
}}
/>Sources: apps/web/app/ee/admin.dub.co/dashboard/programs/page.tsx:311-343, apps/web/app/ee/admin.dub.co/dashboard/programs/page.tsx:240-253, apps/web/app/ee/admin.dub.co/dashboard/page.tsx:34-41
Caution
Deleting a partner's Stripe Express account will fail to remove the account if the partner has already received payouts via Stripe, and will leave the partner account intact if they have already accumulated commissions or leads on Dub.
Sources: apps/web/app/ee/admin.dub.co/dashboard/page.tsx:20-32
Authentication Reset and Support Invites
Operational tools also handle account security recovery and customer engagement. Administrators can reset a user's invalidLoginAttempts counter and clear their lockedAt timestamp when accounts become locked due to failed authentication thresholds. Additionally, administrators can manually dispatch priority Slack Connect invites to users for a specific workspace via the Slack Support Invite tool, bypassing normal plan checks.
<h2 className="text-xl font-semibold">Reset Login Attempts</h2>
<p className="text-sm text-neutral-500">
Reset a user's invalidLoginAttempts and lockedAt fields
</p>
<ResetLoginAttempts />
</div>
<div className="flex flex-col space-y-4 px-5 py-10">
<h2 className="text-xl font-semibold">Slack Support Invite</h2>
<p className="text-sm text-neutral-500">
Manually send a priority Slack Connect invite to a user for a given
workspace (bypasses the plan check).
</p>
<SlackSupportInvite />
</div>Sources: apps/web/app/ee/admin.dub.co/dashboard/page.tsx:43-56
API endpoints handling administrative actions are secured by the withAdmin authorization wrapper, which validates that the requesting session belongs to an authenticated user with a registered admin role in the core project workspace (DUB_WORKSPACE_ID).
export const withAdmin =
(
handler: WithAdminHandler,
{ requiredRoles = [] }: { requiredRoles?: WorkspaceRole[] } = {},
) =>
async (
req: Request,
{ params: initialParams }: { params: Promise<Record<string, string>> },
) => {
const params = (await initialParams) || {};
const session = await getSession();
if (!session?.user) {
return new Response("Unauthorized: Login required.", { status: 401 });
}
const adminRole = await getDubAdminRole(session.user.id);
if (!adminRole) {
return new Response("Unauthorized: Not an admin.", { status: 401 });
}
if (requiredRoles.length > 0 && !requiredRoles.includes(adminRole)) {
return new Response(
`Unauthorized: Missing required admin role(s): ${requiredRoles.join(", ")}.`,
{ status: 403 },
);
}Sources: apps/web/lib/auth/admin.ts:41-66, apps/web/lib/auth/admin.ts:22-39
Domain and System Analytics Monitoring
Registrar Operations and Domain Management
Workspace settings allow administrators and workspace members to manage custom domains, configure default Dub domains, and handle registrar provisioning actions. Workspaces can add custom domains, toggle auto-renewal for Dub-provisioned domains, transfer domains, and archive or delete non-provisioned domains.
{isDubProvisioned && (
<Button
text={
!autoRenew ? "Enable Auto-Renew" : "Disable Auto-Renew"
}
variant="outline"
onClick={() => {
setOpenPopover(false);
openDomainRenewalModal(!autoRenew);
}}
icon={
<Repeat
className={cn(
"h-4 w-4",
!autoRenew ? "text-green-600" : "text-red-600",
)}
/>
}
className="h-9 justify-start px-2 font-medium"
/>
)}
{!primary && (
<Button
text="Set as Primary"
variant="outline"
onClick={() => {
setOpenPopover(false);
setShowPrimaryDomainModal(true);
}}
icon={<Flag2 className="h-4 w-4" />}
className="h-9 justify-start px-2 font-medium"
/>
)}
{canSetAsProgramDomain && (
<Button
text="Set Program Domain"
variant="outline"
onClick={() => {
setOpenPopover(false);
setShowChangeDomainModal(true);
}}
icon={<ConnectedDots4 className="h-4 w-4" />}
className="h-9 justify-start px-2 font-medium"
/>
)}
{!isDubProvisioned && (
<Button
text="Transfer"
variant="outline"
onClick={() => {
setOpenPopover(false);
setShowTransferDomainModal(true);
}}
icon={<FolderInput className="h-4 w-4" />}
className="h-9 justify-start px-2 font-medium"
disabledTooltip={
primary && activeDomainsCount > 1
? "You cannot transfer your workspace's primary domain. Set another domain as primary to transfer this domain."
: undefined
}
/>
)}
<Button
text={archived ? "Unarchive" : "Archive"}
variant="outline"
onClick={() => {
setOpenPopover(false);
setShowArchiveDomainModal(true);
}}
icon={<Archive className="h-4 w-4" />}
className="h-9 justify-start px-2 font-medium"
disabledTooltip={permissionsError || undefined}
/>
{!isDubProvisioned && (
<Button
text="Delete"
variant="danger-outline"
onClick={() => {
setOpenPopover(false);Sources: apps/web/ui/domains/domain-card.tsx:557-643, apps/web/app/app.dub.co/dashboard/slug/ee/settings/domains/page-client.tsx:171-221
Note
When Domain Connect callbacks return to the custom domains settings page, the client inspects search parameters for errors or success states, automatically triggering immediate domain verification revalidations followed by delayed revalidation checks at 4 and 10 seconds.
Sources: apps/web/app/app.dub.co/dashboard/slug/ee/settings/domains/page-client.tsx:78-111
Workspaces can also enable or disable default Dub branded domains for specific links by making PATCH requests to /api/domains/default.
fetch(`/api/domains/default?workspaceId=${id}`, {
method: "PATCH",
body: JSON.stringify({
defaultDomains: newDefaultDomains.filter(
(d) => d !== null,
),
}),
})
.then(async (res) => {Sources: apps/web/app/app.dub.co/dashboard/slug/ee/settings/domains/default/page-client.tsx:102-110
| Domain Slug | Mapped Icon Component | Description / Association |
|---|---|---|
chatg.pt | ChatGPT | OpenAI ChatGPT branded short links |
git.new | GitHubEnhanced | GitHub repository short links |
spti.fi | Spotify | Spotify track and album links |
cal.link | CalendarDays | Calendar scheduling links |
amzn.id | Amazon | Amazon product and affiliate links |
ggl.link | GoogleEnhanced | Google service links |
fig.page | Figma | Figma design file links |
Sources: apps/web/app/app.dub.co/dashboard/slug/ee/settings/domains/default/page-client.tsx:23-42, apps/web/app/app.dub.co/dashboard/slug/ee/settings/domains/default/page-client.tsx:78-88
Platform Analytics and Event Interfaces
The administrative portal provides system-wide analytics and event monitoring interfaces. Administrators access traffic analytics and event logs through dedicated dashboard pages wrapped in suspense boundaries with layout loaders.
export default function AdminAnalytics() {
return (
<Suspense fallback={<LayoutLoader />}>
<div className="w-full">
<Analytics adminPage />
</div>
</Suspense>
);Sources: apps/web/app/ee/admin.dub.co/dashboard/analytics/page.tsx:5-12, apps/web/app/ee/admin.dub.co/dashboard/events/page.tsx:7-16
Tip
The admin events view wraps the core EventsProvider and AnalyticsClient components with the adminPage flag enabled, allowing administrative inspection of platform-wide event streams.
Sources: apps/web/app/ee/admin.dub.co/dashboard/events/page.tsx:7-16
Related
On This Page
OverviewAdmin Authentication and Role GuardsRole Verification and Workspace ValidationEdge Middleware GuardsAccess Blocklists and Restricted PathsUI Navigation FilteringUser Impersonation FlowIdentifier Parsing and Query ResolutionUsage Metrics and SerializationSession Tracking and Impersonation TokensLink and Workspace ModerationLink Search and FilteringWorkspace Disabling and RestorationPartner Network OversightNetwork Partner Applications and MetadataTrusted Partner ManagementProgram and Operational ToolsAffiliate Program Management and Partner Account DeletionsAuthentication Reset and Support InvitesDomain and System Analytics MonitoringRegistrar Operations and Domain ManagementPlatform Analytics and Event InterfacesRelated