Custom domains
Serve your public site at a domain you own — gracechurch.org instead
of grace.psalmly.app. Admin and member portal stay on the Psalmly
domain; the custom domain is public-site only.
When you'd use this
- You already own a domain and want visitors to land at it directly.
- You're moving from an older church website and want to keep the domain pointing to the same place.
- You want a vanity URL on outreach materials (yard signs, postcards, the back of a t-shirt) that doesn't include "psalmly.app".
The two-step flow
We verify DNS first, then provision the cert. That avoids burning cert allowance on hostnames a church doesn't actually control.
- Add the domain. Admin → Settings → Custom domains → Add
domain. Type the hostname (
gracechurch.org) — no protocol, no slash. The row appears with status DNS pending and a panel of DNS records to publish. - Publish two DNS records at your DNS host:
- A TXT record at
_psalmly.<hostname>with the verification token shown in the panel. Proves ownership. - An A record at the apex (
gracechurch.org) pointing to76.76.21.21, OR a CNAME tocname.vercel-dns.comif your DNS host supports CNAME-at-apex (Cloudflare, Route 53 alias).
- A TXT record at
- Wait — or check now. We re-check DNS periodically. When both records resolve, status flips to DNS verified and we immediately ask Vercel to attach the domain + issue the cert. Status walks through Cert provisioning → Live. Don't want to wait for the next automatic pass? Hit Check now on the domain row to re-check that instant.
Typical end-to-end time from "added" to "live" is 10–30 minutes, dominated by DNS propagation. Cloudflare-fronted domains often verify in a couple of minutes; older DNS hosts (GoDaddy, Namecheap web UI) can take an hour or two.
What "live" means
Once the row reads Live:
- Visiting
gracechurch.org/serves your public home page. - Deep links like
gracechurch.org/about,gracechurch.org/give,gracechurch.org/events/<id>all work — anything that's ongrace.psalmly.appis also on your custom domain. - The certificate is auto-renewed by Vercel ahead of expiry. You don't have to do anything.
What does not work on the custom domain — by design:
gracechurch.org/admin/...returns 404. The admin app stays onpsalmly.appso admin authentication isn't fragmented across arbitrary hostnames.gracechurch.org/member/...(or any other authenticated member portal path) — same.- Bare
/c/<slug>URLs — the admin/member routes those handle aren't served on a custom domain.
If a visitor lands on one of those URLs on your custom domain, send them to the Psalmly URL instead.
Status states
| Status | Meaning | What to do |
|---|---|---|
| DNS pending | Records not yet detected. We re-check periodically. | Publish the records; wait for propagation, or hit Check now to re-check immediately. The panel shows a dig command if you want to verify locally. |
| DNS verified | TXT + apex records both resolve. Vercel attach is queued. | Nothing — the cert step runs automatically. |
| Cert provisioning | Vercel is issuing the cert. | Wait — usually completes in seconds, sometimes a minute. |
| Live | Cert issued, routing active. | Visit your hostname. |
| Error | DNS records dropped or the cert step failed (e.g. a CAA record blocking issuance). The row shows the specific reason. | Fix the underlying issue, then hit Check now (or wait for the next automatic check). Error is not a dead end — a successful re-check moves the domain straight back into the pipeline. No need to remove + re-add unless you want a fresh verification token. |
Removing a domain
Use the row's overflow menu → Remove. The domain stops serving your site within ~5 minutes (when the route cache expires). The Vercel cert lingers in their system until its own TTL — that's fine, it just won't route to you.
Why isn't it verifying?
Almost always one of:
- Records not propagated yet. Give it more time (up to an hour
on a slow DNS host), then hit Check now. Run
dig +short _psalmly.<hostname> TXTanddig +short <hostname> A— both should return the values from the panel before we can verify. - TXT value typo. DNS UIs sometimes strip / add quotes; the value should be the raw token from the panel, nothing else.
- CAA record blocking issuance. Some DNS hosts pre-populate a
CAA record that restricts cert issuance to a specific authority.
If you see Error with "misconfigured DNS / CAA blocking",
either remove the CAA record or add
letsencrypt.orgto the allowed authorities. - A record pointing at an old host. Make sure the A record
value is exactly
76.76.21.21and there are no extra A records pointing elsewhere.
What's deferred
- Multiple hostnames per church (e.g. both
gracechurch.organdgrace-church.org). The schema allows it (one row per hostname); the admin UI lets you add a second row. Both will work, but the canonical / redirect setup between them is on you. - Cert / DNS providers other than Vercel. Phase 6 v1 is Vercel only. If you're hosting Psalmly somewhere else, this feature won't work until a small adapter for the new platform's domain API lands.
- Apex + www handling. If you want both
gracechurch.orgANDwww.gracechurch.org, add them as two separate domain rows. Each needs its own DNS record set.
More topics