DNS Setup
Connect a client's custom domain to their Collective Vision deployment.
Instructions for connecting a client's custom domain to their Collective Vision deployment.
Option 1: No custom domain (simplest)
Clients use our shared platform domain. No DNS changes needed.
- Widget src:
https://feedback.ourdomain.com/widget.js - API base:
https://feedback.ourdomain.com - Admin UI:
https://admin.ourdomain.com
The widget and API scope data to the client's workspace via the data-workspace
attribute. This is the fastest path to getting a client live.
Option 2: Client custom domain via CNAME
The client gets a branded URL like feedback.acmecorp.com that routes to our
Worker.
Client-side steps
Step 1: Choose a subdomain
Pick the subdomain that will serve the feedback widget and API. Common choices:
feedback.yourdomain.comvoice.yourdomain.comideas.yourdomain.com
Step 2: Create a CNAME record
In your DNS provider (Cloudflare, Route53, GoDaddy, etc.), add:
| Type | Name | Target | TTL |
|---|---|---|---|
| CNAME | feedback | feedback.ourdomain.com | Auto / 300 |
If using Cloudflare as your DNS provider, set the proxy status to DNS Only (gray cloud) — our Cloudflare account handles the proxying.
Step 3: Notify us
Send us:
- The full subdomain:
feedback.yourdomain.com - Your workspace slug (if already provisioned)
We'll configure the Worker route and CORS on our end.
Step 4: Verify
After we confirm setup (usually within 1 business day):
# Check DNS resolution
dig feedback.yourdomain.com CNAME
# Check health endpoint
curl https://feedback.yourdomain.com/health
# Expected: {"ok":true}
# Check widget loads
curl -I https://feedback.yourdomain.com/widget.js
# Expected: 200 OK, Content-Type: application/javascriptStep 5: Update your embed code
<script
src="https://feedback.yourdomain.com/widget.js"
data-workspace="your-workspace"
data-board="main"
></script>Our-side steps (internal)
When a client requests a custom domain:
1. Add Worker route
In wrangler.toml, add the client's domain to the production environment:
[env.production]
routes = [
{ pattern = "feedback.ourdomain.com/*", zone_name = "ourdomain.com" },
{ pattern = "feedback.acmecorp.com/*", zone_name = "ourdomain.com" }
]Note: The
zone_nameis always our zone, not the client's. Cloudflare routes the traffic to our Worker based on the CNAME pointing to our domain.
2. Add to ALLOWED_ORIGINS
[env.production.vars]
ALLOWED_ORIGINS = "https://feedback.ourdomain.com, https://feedback.acmecorp.com, https://www.acmecorp.com, https://acmecorp.com"Include both the custom feedback domain and the client's main site domain (where the widget is embedded).
3. Configure SSL via Custom Hostnames
For automatic SSL on the client's subdomain, use Cloudflare for SaaS (Custom Hostnames):
# Add custom hostname via Cloudflare API
curl -X POST "https://api.cloudflare.com/client/v4/zones/{zone_id}/custom_hostnames" \
-H "Authorization: Bearer {api_token}" \
-H "Content-Type: application/json" \
-d '{
"hostname": "feedback.acmecorp.com",
"ssl": {
"method": "cname",
"type": "dv"
}
}'Or via the Cloudflare dashboard: SSL/TLS → Custom Hostnames → Add Custom Hostname.
4. Deploy
wrangler deploy --env production5. Verify SSL
curl -vI https://feedback.acmecorp.com/health 2>&1 | grep "SSL certificate"SSL provisioning can take up to 24 hours but usually completes within minutes after the CNAME propagates.
Option 3: Cloudflare for SaaS (recommended at scale)
For onboarding many clients with custom domains, use Cloudflare's SSL for SaaS product. This automates SSL certificate provisioning and doesn't require manual route updates per client.
One-time setup (our side)
- Enable Cloudflare for SaaS on our zone via the dashboard: SSL/TLS → Custom Hostnames
- Set fallback origin:
feedback.ourdomain.com - Configure default Worker route to catch all custom hostnames:
Or use a more specific catch-all pattern that matches your needs.[env.production] routes = [ { pattern = "*/*", zone_name = "ourdomain.com" } ]
Per-client setup
- Add the custom hostname (API or dashboard)
- Client creates their CNAME record
- Cloudflare automatically:
- Validates domain ownership via CNAME
- Provisions and renews DV SSL certificate
- Routes traffic to our Worker
- Add their domain to
ALLOWED_ORIGINSand redeploy
Domain validation
Cloudflare validates the custom hostname via the CNAME record. The client's CNAME pointing to our fallback origin serves as proof of domain control. No TXT records or email validation needed.
Troubleshooting
SSL certificate pending
Symptom: ERR_SSL_PROTOCOL_ERROR or certificate warning
Fix: Wait for CNAME propagation (up to 24 hours). Verify CNAME is correctly set:
dig feedback.clientdomain.com CNAME
# Should return: feedback.ourdomain.com522/523 errors
Symptom: Cloudflare error page with 522 or 523 code
Fix: The Worker route doesn't match the custom domain. Verify:
- The route pattern in
wrangler.tomlincludes the client's domain - The Worker is deployed to the correct environment
- Run
wrangler deployments list --env productionto check
CORS errors
Symptom: Browser console shows Access-Control-Allow-Origin errors
Fix: Add both domains to ALLOWED_ORIGINS:
- The client's main site domain (where widget is embedded):
https://www.acmecorp.com - The custom feedback domain (where API lives):
https://feedback.acmecorp.com
Widget not loading
Symptom: Widget script fails to load or shows network error
Checks:
- Script src matches the domain serving the Worker:
src="https://feedback.acmecorp.com/widget.js" data-workspaceattribute matches the provisioned workspace slug- DNS has propagated:
dig feedback.acmecorp.com - Health check passes:
curl https://feedback.acmecorp.com/health
Mixed content warnings
Symptom: Widget blocked on HTTPS site because script loads over HTTP
Fix: Always use https:// in the script src. Our Worker enforces HTTPS via
Cloudflare's automatic HTTPS rewrites.
Quick reference
| Scenario | DNS action (client) | Config action (us) | SSL |
|---|---|---|---|
| Shared domain | None | Add to ALLOWED_ORIGINS | Automatic |
| Custom subdomain | CNAME → our domain | Add route + ALLOWED_ORIGINS + Custom Hostname | Via Custom Hostnames |
| Custom apex domain | Not supported | — | — |
Note: Apex/root domains (e.g.,
acmecorp.comwithout a subdomain) cannot use CNAME records per DNS spec. Clients must use a subdomain likefeedback.acmecorp.com. Some DNS providers support CNAME flattening (Cloudflare, Route53 ALIAS), but subdomains are strongly recommended.