Skip to content
Docs

Custom Domain

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.

Install the custom-domain block with the Vercel Platforms CLI:

npx @vercel/platforms@latest add custom-domain

You can also install it with the shadcn CLI:

npx shadcn@latest add https://registry.platforms.guide/custom-domain.json
  • 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
custom-domain.tsx
import { CustomDomain } from '@/components/blocks/custom-domain';
 
export default function DomainSettings() {
  return <CustomDomain defaultDomain="docs.example.com" />;
}

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

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;
}

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,
  };
}
PropTypeRequiredDescription
defaultDomainstringNoOptional pre-filled domain value

Handles the DNS record display and refresh logic:

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

Shows visual status of domain configuration:

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

Styled inline code display for domain values:

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

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
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>
  );
}
  • 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
Last updated September 3, 2026

Was this helpful?

supported.