Skip to content
Docs

DNS Table

The DNS Table block provides a clean, user-friendly interface for displaying DNS records that users need to configure. It's designed for platforms that guide users through domain configuration, offering one-click copying of values and clear visual organization. This component is essential for domain management interfaces in platforms like Mintlify and Hashnode.

Install the dns-table block with the Vercel Platforms CLI:

npx @vercel/platforms@latest add dns-table

You can also install it with the shadcn CLI:

npx shadcn@latest add https://registry.platforms.guide/dns-table.json
  • One-click copying: Each DNS value has a copy button with visual confirmation
  • All record types: Supports A, AAAA, CNAME, MX, NS, SOA, PTR, SRV, TXT, and CAA records
  • Responsive design: Table adapts gracefully to different screen sizes
  • Monospace formatting: DNS values displayed in monospace font for clarity
  • TTL support: Optional TTL values with "Auto" as default
  • Empty state handling: Clean message when no records are present
  • Accessibility: Full keyboard navigation and screen reader support
dns-table.tsx
import { DNSTable } from '@/components/blocks/dns-table';
 
const records = [
  {
    type: 'CNAME',
    name: 'docs',
    value: 'cname.vercel-dns.com',
    ttl: '3600',
  },
  {
    type: 'TXT',
    name: '_vercel',
    value: 'vc-domain-verify=abc123def456...',
  },
];
 
export default function DNSConfiguration() {
  return <DNSTable records={records} />;
}
dns-table.tsx
import { DNSTable } from '@/components/blocks/dns-table';
import { CustomDomain } from '@/components/blocks/custom-domain';
 
export default function DomainSettings() {
  // The CustomDomain component internally uses DNSTable
  // to display required DNS records
  return <CustomDomain defaultDomain="example.com" />;
}
PropTypeRequiredDefaultDescription
recordsDNSRecord[]YesArray of DNS records to display
copyTimeoutnumberNo2000Duration to show copy confirmation in milliseconds
type DNSRecord = {
  type:
    | 'A'
    | 'AAAA'
    | 'CNAME'
    | 'MX'
    | 'NS'
    | 'SOA'
    | 'PTR'
    | 'SRV'
    | 'TXT'
    | 'CAA';
  name: string;
  value: string;
  ttl?: string;
};
  • A: Maps domain to IPv4 address (e.g., 192.0.2.1)
  • AAAA: Maps domain to IPv6 address (e.g., 2001:db8::1)
  • CNAME: Creates alias to another domain
  • MX: Specifies mail servers for domain
  • NS: Identifies authoritative nameservers
  • SOA: Contains zone administrative information
  • PTR: Reverse DNS lookup (IP to domain)
  • SRV: Specifies service locations (port/host)
  • TXT: Stores text data (verification, SPF, etc.)
  • CAA: Controls SSL certificate authorities
dns-table.tsx
import { DNSTable } from '@/components/blocks/dns-table';
import { useState } from 'react';
 
export function DomainVerification({ domain }) {
  const [verificationRecord] = useState({
    type: 'TXT',
    name: `_vercel.${domain}`,
    value: `vc-domain-verify=${generateVerificationCode()}`,
  });
 
  return (
    <div className="space-y-4">
      <h3>Add this TXT record to verify ownership:</h3>
      <DNSTable records={[verificationRecord]} />
      <Button onClick={checkVerification}>Check Verification</Button>
    </div>
  );
}
import { DNSTable } from '@/components/blocks/dns-table';
 
const complexDNSSetup = [
  // Root domain A records
  {
    type: 'A',
    name: '@',
    value: '76.76.21.21',
  },
  // Subdomain CNAME
  {
    type: 'CNAME',
    name: 'www',
    value: 'cname.vercel-dns.com',
  },
  // Mail configuration
  {
    type: 'MX',
    name: '@',
    value: '10 mail.example.com',
    ttl: '3600',
  },
  // SPF record for email
  {
    type: 'TXT',
    name: '@',
    value: 'v=spf1 include:_spf.example.com ~all',
  },
];
 
export default function CompleteDNSSetup() {
  return (
    <Card>
      <CardHeader>
        <CardTitle>Required DNS Records</CardTitle>
        <CardDescription>
          Add all these records to complete your setup
        </CardDescription>
      </CardHeader>
      <CardContent>
        <DNSTable records={complexDNSSetup} />
      </CardContent>
    </Card>
  );
}

The copy button component used for each DNS value:

dns-table.tsx
import { DNSCopyButton } from '@/components/blocks/dns-table';
 
<DNSCopyButton
  text="76.76.21.21"
  copyTimeout={3000} // Optional: customize confirmation duration
/>;

The component uses Tailwind classes and can be customized through your theme configuration:

/* Customize table appearance */
.dns-table {
  @apply border-2 border-primary;
}
 
/* Customize copy button */
.dns-copy-button {
  @apply hover:bg-primary/10;
}
  • Value validation: Validate DNS values before displaying to prevent copy errors
  • Record grouping: Group related records together (e.g., all A records)
  • Clear instructions: Provide context about where users should add these records
  • Progress tracking: Consider showing which records have been configured
  • Help links: Include links to DNS provider documentation when possible
dns-table.tsx
// Example: Provider-specific instructions
const DNSInstructions = ({ provider, records }) => {
  const getProviderInstructions = (provider) => {
    switch (provider) {
      case 'cloudflare':
        return 'Log in to Cloudflare and navigate to DNS settings';
      case 'godaddy':
        return 'Access your GoDaddy DNS Management panel';
      default:
        return 'Add these records in your DNS provider';
    }
  };
 
  return (
    <div className="space-y-4">
      <Alert>
        <AlertDescription>{getProviderInstructions(provider)}</AlertDescription>
      </Alert>
      <DNSTable records={records} />
    </div>
  );
};
Last updated September 3, 2026

Was this helpful?

supported.