← Back to blog

How to add custom domains for your users in an AI-built SaaS (Lovable, Base44, Bolt, v0)

Daniel Sternlicht·
lovablebase44boltv0ai builderscustom domainswhite label saasno code
How to add custom domains for your users in an AI-built SaaS (Lovable, Base44, Bolt, v0)

AI app builders do not ship multi-tenant custom domains. The "custom domain" setting in Lovable, Base44, Bolt, v0 or Replit connects one domain, the one your app lives on. To give every customer portal.theirbrand.com, you add a custom-domains API to your AI-built SaaS. That is about an hour of work, whichever builder you used.

You shipped a SaaS in Lovable, Base44, Bolt, v0 or Replit. It works. Your first paying customers are using it. Then one of them writes:

"Can I use my own domain for this? Something like portal.mybrand.com instead of yourapp.com/customer/123?"

You go looking in the builder's dashboard, find a "custom domain" setting, and realise within a minute that it is not the thing you need.

What each builder's "custom domain" feature actually does

Checked against each vendor's own documentation and support pages on 19 August 2026:

BuilderDomain featurePlan requiredRecords it asks forDomains for your users
LovableOne domain for your appPaid plans onlyA → 185.158.133.1, TXT _lovable = lovable_verify=…No
BoltOne domain for your appPaid (Pro $25/mo, Teams $30/member/mo)TXT to verify, then CNAME on www + ALIAS at rootNo
ReplitOne domain per deploymentAutoscale, Reserved VM or Static (not Scheduled)A records + TXT replit-verify=…No
Base44One domain for your appPaid plansCNAME (or A) from the project settings panelNo
v0One domain per deploymentVercel accountVercel's apex A or per-project CNAMENo

The right-hand column is the same on every row, and that is the whole post.

Notice the shape they share: every one of them verifies a single hostname interactively, through a dashboard, with a TXT record you paste in by hand. That is a fine design for the one domain your company owns. It is structurally unusable for a hundred customer domains, because there is no API to call, no way to script it, and someone at your company would have to click through the flow every time a customer signed up.

One trap worth pulling out of that table, because it costs people certificates months later: those verification TXT records are not one-time keys. Replit's documentation is explicit that a missing or modified replit-verify= record blocks verification and certificate renewal, and that it must stay in DNS for the lifetime of the domain. The same is true in practice on the others. Tidying up "the setup record" six months later is a scheduled outage.

Why none of them ship the multi-tenant version

It is not an oversight. Serving a domain your customer owns means running infrastructure the builder does not otherwise need:

  • A TLS certificate per customer hostname, issued over ACME and renewed on a schedule forever, with the failures retried and alerted.
  • SNI-based certificate selection at the edge, so one IP can serve the right certificate to thousands of different hostnames.
  • DNS monitoring, because customers delete records, move registrars, and switch on Cloudflare's proxy without telling you.
  • Rate-limit management, since Let's Encrypt caps failed validations per identifier per hour and a naive retry loop will lock you out of issuance.

Those four things are a product. The AI builders built a different product.

Where your backend code lives, per builder

You need somewhere to run one API call and one webhook handler. Every builder gives you that:

  • Lovable exports a Vite or Next.js project to GitHub. Host it on Vercel and call the API from there. The setup is in hosting a Lovable app on a custom domain.
  • Base44 has built-in backend functions.
  • Bolt deploys to a Node runtime with your own server code.
  • v0 components drop into your own Next.js project, where you have full backend control. If you are on Next.js, the multi-tenant guide covers the host-routing half.
  • Replit gives you a hosted Node or Python backend out of the box.

From any of those, calling api.domainee.dev is a fetch.

The integration

Domainee is a custom domains API for SaaS with a native MCP server — 50 domains and 100 GB free. When a customer enters their domain in your dashboard:

const res = await fetch("https://api.domainee.dev/v1/domains", {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${process.env.DOMAINEE_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    hostname: "portal.acmeco.com",
    originUrl: "https://your-ai-built-app.com",  // your builder's hosted URL
    metadata: { customerId: "cust_123" },         // echoed back in webhooks
  }),
});

const { domain } = await res.json();
// domain.dnsRecords holds the CNAME the customer adds at their registrar.

Render dnsRecords in your UI with a copy button. One CNAME is all the customer touches.

Then handle the webhook when the certificate issues:

// POST /webhooks/domainee in your backend
const event = await req.json();

if (event.type === "domain.verified") {
  // event.data.metadata.customerId tells you whose domain went live.
  // Mark their instance live, email them, done.
}

That is the feature. The certificate, the renewal job, the drift detection when a customer breaks their DNS: not your problem.

The one thing you still have to build

Routing. Once traffic for portal.acmeco.com reaches your origin, your app has to work out which customer it belongs to. The edge forwards the original hostname:

X-Forwarded-Host:        portal.acmeco.com
X-Domainee-Original-Host: portal.acmeco.com

Read that header, look up the tenant, render their data. In a Lovable or v0 export that is a few lines in Next.js middleware; in Base44 or Replit it is a lookup at the top of your handler.

Route on the Host header, never on the SNI. They usually carry the same value, but under HTTP/2 a browser can reuse one connection for several hostnames, and the SNI will then belong to a different tenant than the request does. That is a real way to serve one customer's data to another.

What you can build with it

The full list is at /use-cases.

Build or buy

If you would rather build it, the honest scope is: an ACME client with DNS or HTTP validation, certificate storage and rotation, an edge that selects certificates by SNI, a DNS poller, a webhook system, and rate-limit-aware retry logic. The Cloudflare SSL for SaaS guide walks the most common DIY route, and how SSL provisioning works covers the mechanics underneath.

That is a reasonable project for a team with spare infrastructure engineers. If you built your SaaS in an AI app builder, you probably do not have those, which is rather the point. Pricing has the numbers; the first 50 customer domains are free.

FAQ

Can Lovable, Bolt or Replit give each of my users their own domain? No. Every one of them connects a single hostname for your app, verified by hand through a dashboard with a TXT record. There is no API to run that flow per customer, so it cannot be scripted around. Multi-tenant custom domains are a separate layer you add.

Do I have to leave my AI builder to do this? No. You need somewhere to run one API call and one webhook handler, and every builder gives you that: Base44 functions, Bolt's Node runtime, Replit's backend, or a Lovable or v0 export deployed on Vercel.

What does my customer have to do? Add one CNAME record at their registrar, pointing their hostname at the platform edge. The certificate issues automatically once that record resolves. If their DNS is on Cloudflare, they also need the proxy set to DNS only, which the API flags for you.

Why does deleting the verification TXT record break things later? Because it is re-checked, not consumed. Replit documents this explicitly: removing or changing the replit-verify= record blocks both verification and certificate renewal. Treat every verification record a vendor gives you as permanent.

How long does it take a customer's domain to go live? Usually minutes. The wait is DNS, not the certificate: the record has to be visible to the validating resolvers before issuance runs. Checking a hostname before the record exists is the common way to make it slow, since a cached negative answer can persist for up to an hour.

How many customer domains can I connect for free? Fifty, on Domainee's free tier, along with 100 GB of bandwidth and no card. That covers the whole validation phase for most products, which is the point at which you find out whether the feature was worth building.