Quickstart
Define the required DNS records in your application and open Domain0 Connect for your customer.
This example uses Next.js App Router. Your server defines the DNS intent. The browser receives only a connection-scoped session and opens the customer flow.
1. Define the connection on your server
import { createDomain0PlatformClient } from 'domain0'
import { DomainNameSchema } from 'domain0/contracts'
import { z } from 'zod'
const platform = createDomain0PlatformClient({
baseUrl: 'https://domain0.dev/api/domain0/',
apiKey: () => process.env.DOMAIN0_API_KEY!,
})
export async function POST(request: Request) {
// Authenticate the request and load the product resource this user owns.
const input = z.object({ domain: DomainNameSchema }).parse(await request.json())
const { connection } = await platform.createConnection({
intent: {
domain: input.domain,
// These values come from your product configuration or database.
records: [
{
host: '@',
type: 'A',
value: '192.0.2.10',
ttl: 300,
},
{
host: 'www',
type: 'CNAME',
value: 'edge.your-product.com',
ttl: 300,
},
],
},
})
const access = await platform.issueConnectionToken(connection.id, {
origin: new URL(request.url).origin,
})
return Response.json({ connectionId: connection.id, ...access })
}2. Add the same-origin bridge
import { forwardDomain0ConnectionRequest } from 'domain0/server'
async function forward(
request: Request,
context: { params: Promise<{ path: string[] }> },
) {
const { path } = await context.params
return forwardDomain0ConnectionRequest({
request,
path,
upstreamBaseUrl: 'https://domain0.dev/api/domain0/',
})
}
export const GET = forward
export const POST = forwardThe helper allows only connection-scoped routes. It forwards the bearer token and exact origin, but never cookies, API keys, or unrelated headers.
3. Open Domain0 Connect
import {
ConnectionIdSchema,
IssueConnectionTokenResponseSchema,
createDomain0Client,
domain0,
} from 'domain0'
const SessionSchema = IssueConnectionTokenResponseSchema.extend({
connectionId: ConnectionIdSchema,
})
const response = await fetch('/api/domain-session', {
method: 'POST',
headers: { 'content-type': 'application/json' },
body: JSON.stringify({ domain: 'customer.example' }),
})
if (!response.ok) throw new Error('Domain session creation failed')
const session = SessionSchema.parse(await response.json())
const connectionId = ConnectionIdSchema.parse(session.connectionId)
const client = createDomain0Client({
baseUrl: '/api/domain0/',
token: session.accessToken,
})
await domain0.connectDomain({
client,
connectionId,
applicationName: 'Your product',
onSuccess: ({ connection }) => {
console.log(`${connection.intent.domain} is active`)
},
})The customer sees the saved domain and records. They never type DNS values. The dialog owns provider detection, provider selection, authorization, exact change review, setup, and authoritative verification.
Authenticate your session endpoint
Protect /api/domain-session with your own user and tenant authorization.
Resolve record values from trusted product data; do not accept arbitrary DNS
records from an untrusted browser request.