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-domainYou 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
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:
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:
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,
};
}| Prop | Type | Required | Description |
|---|---|---|---|
defaultDomain | string | No | Optional pre-filled domain value |
Handles the DNS record display and refresh logic:
<DomainConfiguration domain="example.com" className="custom-class" />Shows visual status of domain configuration:
<DomainStatusIcon domain="example.com" />Styled inline code display for domain values:
<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
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
Was this helpful?