Custom Domain
Complete domain management interface with DNS verification and status tracking
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-domainFeatures
- 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
import { CustomDomain } from "@/components/blocks/custom-domain";
export default function DomainSettings() {
return <CustomDomain defaultDomain="docs.example.com" />;
}Server Actions
The component relies on two server actions that you need to implement:
addDomain(domain: string)
Adds a domain to your Vercel project:
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:
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:
<DomainConfiguration domain="example.com" className="custom-class" />DomainStatusIcon
Shows visual status of domain configuration:
<DomainStatusIcon domain="example.com" />InlineSnippet
Styled inline code display for domain values:
<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
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