Implementation Plan: Split-Origin Architecture for Custom Domains Problem Analysis The current setup fails because we are attempting to use tinyslash.com (hosted on Vercel) as the fallback origin for Cloudflare for SaaS. Since Vercel uses Cloudflare internally, this creates a "Cloudflare behind Cloudflare" conflict (Error 1000), preventing successful SSL provisioning and request routing for custom domains.
Goal Implement a clean separation of concerns:
Frontend (tinyslash.com): Stays on Vercel. Handles UI, Marketing, and standard links. SaaS Origin (api.tinyslash.com): A new dedicated subdomain pointing directly to Render. Handles ALL custom domain traffic. Architecture Origin: api.tinyslash.com API Calls User visits go.brand.com Cloudflare for SaaS Render Backend User visits tinyslash.com Vercel Frontend Required Steps
- DNS Configuration (User Action Required) The user must create a new DNS record in their Cloudflare/DNS provider:
Type: CNAME Name: api Target: api.tinyslash.com Proxy Status: DNS Only / Grey Cloud (CRITICAL: Must NOT be proxied) 2. Render Configuration (User Action Required) Go to Render Dashboard -> URL Service -> Settings -> Custom Domains. Add api.tinyslash.com. Wait for Render to verify ownership and issue its own SSL certificate. Verification: curl https://api.tinyslash.com/health should return 200 OK. 3. Backend Code Updates We need to update CloudflareSaasService.java and application.yml to use api.tinyslash.com as the fallback_origin.
[MODIFY] CloudflareSaasService.java Update fallbackOrigin logic to prioritize api.tinyslash.com. [MODIFY] application-prod.yml Update cloudflare.saas.fallback-origin to api.tinyslash.com. 4. Cloudflare SaaS Configuration (User Action Required) In Cloudflare Dashboard -> SSL/TLS -> Custom Hostnames. Update "Fallback Origin" to api.tinyslash.com. 5. Frontend Updates Update CustomDomainManager.tsx and help text to instruct users to point CNAMEs to tinyslash.com (which we will internally map to api.tinyslash.com via Cloudflare) OR point their CNAMEs to api.tinyslash.com directly? Correction: The PROXY_DOMAIN displayed to users should ideally be tinyslash.com (for branding) but Cloudflare needs to know to route it to api.tinyslash.com. Actually, the standard practice is users CNAME to custom.tinyslash.com or something similar. If users CNAME to tinyslash.com (Vercel), Vercel won't know what to do with go.brand.com. Verdict: Users should CNAME to the SaaS Origin or a specific CNAME target we control. Let's stick to the plan: Users CNAME to tinyslash.com? NO. Users should CNAME to a hostname that resolves to the Cloudflare Worker or the SaaS Origin. If we use api.tinyslash.com as the SaaS origin, users should CNAME to api.tinyslash.com? No, that exposes "api". Common pattern: cname.tinyslash.com which is a CNAME to api.tinyslash.com. Refined Plan: We will tell users to CNAME to tinyslash.com IF we can configure Cloudflare to intercept that. But simpler is telling them to point to api.tinyslash.com (or cname.tinyslash.com). Let's check CustomDomainManager.tsx to see what PROXY_DOMAIN is. It is tinyslash.com. We should likely update PROXY_DOMAIN to api.tinyslash.com (or better, go.tinyslash.com aliased to it) to ensure traffic hits the right entry point. Execution Checklist Step 1: User adds api.tinyslash.com CNAME (Grey Cloud) -> Render. Step 2: User adds api.tinyslash.com to Render Custom Domains. Step 3: Update Backend application-prod.yml to set cloudflare.saas.fallback-origin: api.tinyslash.com. Step 4: Update Frontend CustomDomainManager.tsx to display api.tinyslash.com as the CNAME target. Why this works go.brand.com (User) -> CNAME api.tinyslash.com. api.tinyslash.com resolves to Render IP. Cloudflare sees the request matches a Custom Hostname. Cloudflare terminates SSL for go.brand.com. Cloudflare forwards request to Origin api.tinyslash.com. api.tinyslash.com is on Render (not Vercel), so no looping. Render backend receives request, sees Host: go.brand.com, looks up domain, serves content. This eliminates Vercel completely from the custom domain path.