Custom domains

Experimental, pro-only. Ask Sankalp ([email protected]) to flip your org to the pro plan if you want in.

A custom domain lets your share URLs live at your hostname instead of anchorify.io. After setup, every public share owned by your org also resolves at:

https://docs.acme.com/<project>/<slug>

…in addition to the canonical https://anchorify.io/<org>/<project>/<slug>. Both URLs serve the same page; the canonical one keeps working.

Limits

What Limit
Domains per org 1
Plan required pro
Hostname format lowercase, ≥1 dot, ≤253 chars (e.g. docs.acme.com)
Subdomains recommended (e.g. docs., share.)
Apex domains (acme.com) possible but not supported by every DNS provider — see below
www. handling DIY — see below

Setup flow

  1. Get on the pro plan. Custom domains are gated behind both your org being on pro and the server-side CUSTOM_DOMAINS_ENABLED=1 flag. If either is off, the dashboard shows a "this is a pro feature" stub instead of the form.

  2. Add the domain. Visit /dashboard/settings/domain and enter your hostname (docs.acme.com). The page returns a TXT record:

    Name:  _jf-verify.docs.acme.com
    Value: <random token>
    
  3. Add that TXT record at your DNS provider. Different providers handle this differently — Cloudflare DNS, Namecheap, GoDaddy, Route 53, etc. all have their own UI. Wait a few minutes for propagation.

  4. Click "Verify now". We resolve the TXT record server-side. On a match, the row flips from pending to provisioning and we ask Cloudflare to issue an SSL cert for your hostname.

  5. Wait 1–5 minutes for the cert. The dashboard badge stays Provisioning until Cloudflare reports ssl.status = active. After that, it flips to Active and your domain is live.

If the cert provisioning fails (most commonly a CAA record blocking Let's Encrypt), the badge flips to Failed and we show Cloudflare's error verbatim. Fix the underlying DNS issue and click Retry.

Apex vs subdomain

We strongly recommend a subdomain (docs.acme.com, share.acme.com, etc.) over the apex (acme.com).

Subdomains use a CNAME pointing at our origin pool, which every DNS provider supports.

Apex domains can't have CNAMEs at the zone root per the DNS spec — you'd need ALIAS / ANAME / CNAME-flattening, which not every DNS provider supports:

Provider Apex support
Cloudflare DNS yes (CNAME flattening)
Route 53 yes (ALIAS records)
Vercel DNS yes
GoDaddy no
Namecheap no

If your DNS host doesn't support apex flattening, point a subdomain at us and 301 the apex to it at your DNS host's level. We don't help configure the apex-side DNS.

www. handling

Anchorify only allows one custom hostname per org. If you want both acme.com and www.acme.com to serve, you have two options:

  1. Pick one — say, acme.com — and set up a 301 from www.acme.com to it at your DNS host's level (most providers offer "redirect to URL" rules).
  2. Add the other one as a separate hostname on a different org if you really want both serving Anchorify content.

Most users land on a single subdomain (docs.acme.com) and never have to think about this.

Members-only shares on custom domains

Anchorify session cookies live on anchorify.io, not on your custom hostname. Browsers don't let one host see another host's cookies — that's a security feature of the web, not a Anchorify limitation.

So when a visitor hits a members-visibility share on your custom domain, we 302 them to the canonical anchorify.io URL so we can read their session cookie and render the share.

URL bar limitation: post-redirect, the browser shows anchorify.io/<org>/<project>/<slug> — not your custom hostname. Public + unlisted shares aren't affected; they render in place on the custom domain.

If your org is mostly publishing internal/members-only content, the custom domain is probably less useful for you than for an org publishing public deliverables.

Removal

Click Remove domain on the dashboard. We delete the row + free the hostname slot immediately, so:

  • Your shares stop serving from your custom hostname (they continue to serve from anchorify.io).
  • Another pro org can claim the same hostname (with their own fresh TXT verification + cert flow).

Cleanup note (validation cohort): the Cloudflare-side custom_hostname row + the issued cert aren't auto-deleted on removal — Sankalp cleans those up by hand. The hostname is fully released on the Anchorify side. This is a known follow-up; see services/domains.ts for context.

Routing details

Once your domain is Active, requests to https://docs.acme.com/<path> are internally rewritten to /acme/<path> and served by the same code that powers the canonical URLs. Some routes are explicitly not served on custom domains and 404 instead:

  • /dashboard, /onboarding, /auth/*, /api/*, /admin, /_admin
  • /_dashboard, /_list, /_export, /_import, /_publish
  • /docs/*, /privacy, /terms

Those are Anchorify surfaces, not your org's surfaces — they always live on anchorify.io.

Why CF gets all the cert work

We use Cloudflare for SaaS to issue + serve the certs. That avoids us managing Let's Encrypt directly per hostname (renewals, ACME challenges, key rotation) and gets us a CDN edge cache for free. The trade-off is that you need a clean DNS path that Cloudflare can validate, and apex support depends on your DNS host (above).