Collective Vision

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.com
  • voice.yourdomain.com
  • ideas.yourdomain.com

Step 2: Create a CNAME record

In your DNS provider (Cloudflare, Route53, GoDaddy, etc.), add:

TypeNameTargetTTL
CNAMEfeedbackfeedback.ourdomain.comAuto / 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/javascript

Step 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_name is 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 production

5. 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.

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)

  1. Enable Cloudflare for SaaS on our zone via the dashboard: SSL/TLS → Custom Hostnames
  2. Set fallback origin: feedback.ourdomain.com
  3. Configure default Worker route to catch all custom hostnames:
    [env.production]
    routes = [
      { pattern = "*/*", zone_name = "ourdomain.com" }
    ]
    Or use a more specific catch-all pattern that matches your needs.

Per-client setup

  1. Add the custom hostname (API or dashboard)
  2. Client creates their CNAME record
  3. Cloudflare automatically:
    • Validates domain ownership via CNAME
    • Provisions and renews DV SSL certificate
    • Routes traffic to our Worker
  4. Add their domain to ALLOWED_ORIGINS and 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.com

522/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.toml includes the client's domain
  • The Worker is deployed to the correct environment
  • Run wrangler deployments list --env production to 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:

  1. Script src matches the domain serving the Worker: src="https://feedback.acmecorp.com/widget.js"
  2. data-workspace attribute matches the provisioned workspace slug
  3. DNS has propagated: dig feedback.acmecorp.com
  4. 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

ScenarioDNS action (client)Config action (us)SSL
Shared domainNoneAdd to ALLOWED_ORIGINSAutomatic
Custom subdomainCNAME → our domainAdd route + ALLOWED_ORIGINS + Custom HostnameVia Custom Hostnames
Custom apex domainNot supported

Note: Apex/root domains (e.g., acmecorp.com without a subdomain) cannot use CNAME records per DNS spec. Clients must use a subdomain like feedback.acmecorp.com. Some DNS providers support CNAME flattening (Cloudflare, Route53 ALIAS), but subdomains are strongly recommended.

On this page