Custom Domain

Complete domain management interface with DNS verification, status tracking, and automatic configuration guidance

Custom Domain
The custom domain for your site.

Overview

The Custom Domain block provides a comprehensive solution for platforms that need to offer custom domain functionality to their users. It handles the entire domain configuration flow including DNS verification, real-time status updates, and clear configuration instructions. This is essential for platforms like Mintlify and Hashnode that allow users to serve content from their own domains.

Installation

npx @vercel/platforms@latest add custom-domain

Features

  • Real-time DNS verification: Automatically checks domain configuration every 20 seconds
  • Smart DNS record detection: Determines whether TXT verification, CNAME, or A records are needed
  • Visual status indicators: Clear icons show pending, invalid, or successful configuration
  • One-click copying: Users can easily copy DNS values with confirmation feedback
  • Responsive DNS table: Clean presentation of required DNS records
  • Automatic domain validation: Validates domain format and converts to lowercase

Usage

custom-domain.tsx
import { CustomDomain } from '@/components/blocks/custom-domain'

export default function DomainSettings() {
  return (
    <CustomDomain
      defaultDomain="docs.example.com"
    />
  )
}

Component States

The component intelligently handles multiple configuration states:

1. Initial Setup

User enters their custom domain and saves it to begin the configuration process.

2. Pending TXT Verification

Custom Domain
The custom domain for your site.

Shows when domain ownership needs to be verified through TXT records.

3. CNAME Configuration

Custom Domain
The custom domain for your site.

Displays CNAME records for subdomain configuration (e.g., docs.example.com).

4. Apex Domain Configuration

Custom Domain
The custom domain for your site.

Shows A records for root domain configuration (e.g., example.com).

5. Successfully Configured

Custom Domain
The custom domain for your site.

Confirms when the domain is properly configured and ready to use.

Server Actions

The component relies on two server actions that you need to implement:

addDomain(domain: string)

Adds a domain to your Vercel project:

vercel.ts
import { vercel } from '@/lib/vercel'

export async function addDomain(domain: string) {
  const response = await vercel.projects.addProjectDomain({
    idOrName: process.env.PROJECT_ID,
    requestBody: {
      name: domain,
      redirect: null,
      gitBranch: null
    }
  })
  return response
}

getDomainStatus(domain: string)

Checks the current DNS configuration status:

vercel.ts
export async function getDomainStatus(domain: string) {
  const response = await vercel.domains.getDomainConfig({
    domain
  })

  return {
    status: response.verified
      ? "Valid Configuration"
      : response.verification
      ? "Pending Verification"
      : "Invalid Configuration",
    dnsRecordsToSet: response.verification?.dns || response.dns
  }
}

Props

Prop

Type

Subcomponents

DomainConfiguration

Handles the DNS record display and refresh logic:

custom-domain.tsx
<DomainConfiguration
  domain="example.com"
  className="custom-class"
/>

DomainStatusIcon

Shows visual status of domain configuration:

custom-domain.tsx
<DomainStatusIcon domain="example.com" />

InlineSnippet

Styled inline code display for domain values:

custom-domain.tsx
<InlineSnippet>_vercel.example.com</InlineSnippet>

DNS Record Types

The component supports all common DNS record types:

  • TXT: Domain ownership verification
  • CNAME: Subdomain pointing
  • A: IPv4 address mapping
  • AAAA: IPv6 address mapping
  • MX: Mail server configuration
  • NS: Nameserver delegation

Integration Example

app/settings/domains/page.tsx
// app/settings/domains/page.tsx
import { CustomDomain } from '@/components/blocks/custom-domain'
import { getCurrentUserDomain } from '@/lib/db'

export default async function DomainsPage() {
  const currentDomain = await getCurrentUserDomain()

  return (
    <div className="container mx-auto py-8">
      <h1 className="text-2xl font-bold mb-6">Domain Settings</h1>
      <CustomDomain defaultDomain={currentDomain} />
    </div>
  )
}

Best Practices

  • Rate limiting: Implement rate limiting on domain addition to prevent abuse
  • Domain validation: Validate domain ownership before allowing configuration
  • Error handling: Provide clear error messages for invalid domains
  • SSL certificates: Vercel automatically provisions SSL certificates once configured
  • Monitoring: Track domain configuration success rates and common issues