Hosting & Domains
Put your website online on a domain you own, with HTTPS set up for you. TellWang serves static sites and full Next.js servers (SSR + server components + API routes), publishes records for managed domains, and gives you the exact records when DNS lives elsewhere.
Ship a static frontend
Upload your built static site as a JSON map of path → content. index.html is required (the frontend is served SPA-rooted there). TellWang publishes the files and routes the Wok in one step:
curl -X POST https://tellwang.com/v1/woks/$WOK/frontend \
-H "Authorization: Bearer $TELLWANG_KEY" \
-H "Content-Type: application/json" \
-d '{"files":{
"index.html": "<!doctype html>...",
"assets/app.js": "console.log(\"hi\")",
"assets/style.css": "body{margin:0}"
}}'
# → 200 { wok_id, files, bytes, frontend_url }Same-origin Supabase paths — the edge proxies /rest/v1, /auth/v1, /storage/v1, /functions/v1, and /realtime/v1 verbatim to your Wok's services, so a supabase-js client pointed at frontend_url needs no CORS configuration. Edge functions that return text/event-stream are proxied unbuffered for SSE, and WebSocket Upgrade handshakes pass through the same functions route. Before forwarding a function call, TellWang overwrites X-TellWang-Client-IP with the validated end-user address. Cloudflare forwarding headers are accepted only from Cloudflare's published networks; direct and DNS-only domains fall back to the socket peer. Functions can use that private header for abuse controls without trusting browser-supplied forwarding headers. Hosted pages send MIME-sniffing and referrer-policy response headers at the shared edge while preserving iframe embedding for dashboard previews and customer integrations. Apps that need a narrower frame policy can add their own CSP. GET /frontend lists deployed files + sizes; DELETE /frontend tears down the edge route + clears the bundle.
Files follow URL routes — index.html is the page at /; about/index.html is a different page at /about/. A nested index is not a second checkout or an alternate homepage. Keep both when both routes are intentional, and use the browser's actual path when choosing which file to edit. For site-wide UI, inspect shared assets and every routed document that owns the repeated element.
Redirects — include a Netlify-style _redirects file for the common cases: /old /new 301, /docs/* /help/:splat 308, /products/* https://shop.example.com/products/:splat 308, /app/* /index.html 200, or /blog/* /404.html 404. TellWang supports exact paths, one * splat, internal or external HTTP(S) destinations for 3xx redirects, and statuses 200, 301, 302, 307, 308, and 404. A 3xx redirect preserves the visitor's query string. Rewrites with status 200 remain local. A 404 rule is file-existence-aware: real files and directory indexes still serve normally, and only misses fall back to the target file with HTTP 404. Unsupported or unsafe lines are skipped; the SPA fallback still handles everything else.
Server-side rendering (Next.js)
Static hosting covers SPAs and next export. When the app renders on the server — Next.js App Router server components, app/api route handlers, getServerSideProps, middleware — switch the Wok to SSR mode: a Node process runs your build, and the Wok's URL points at it instead of the file server. The same /rest/v1·/auth/v1·/storage/v1 proxies stay in front, and from server code the Wok's database is one hop away at http://rest:3000 (the container gets SUPABASE_URL + keys in its env).
Build with output: 'standalone' in next.config.js — that makes next build emit a self-contained server.js plus a trimmed node_modules. Pack the .next/standalone directory (copy .next/static and public into it) and POST the tarball:
# after `next build` with output:'standalone'
cp -r .next/static .next/standalone/.next/static
cp -r public .next/standalone/public # if you have one
tar czf - -C .next/standalone . | curl -X POST \
https://tellwang.com/v1/woks/$WOK/appserver/deploy \
-H "Authorization: Bearer $TELLWANG_KEY" \
-H "Content-Type: application/gzip" --data-binary @-
# → 200 { wok_id, mode:"ssr", files, bytes, url, healthy:true }Building inside Wang? Its hosted Agent Cell checks out the staging Wok, builds with native file and shell tools, and publishes through TellWang's authenticated release path. POST /appserver/static flips a Wok back to static file serving.
Preview keeps failed candidates. A failed test or verification records the exact evidence but does not automatically restore an older Preview. Preview is where breaking work stays visible for diagnosis and revision. Roll it back explicitly when that is the intended change. Published releases retain their guarded recovery policy.
SSR HTML includes TellWang's same-origin preview and replay loader so element annotations work on server-rendered pages too. Every browser sends the selected HTML element descriptor; in Chrome, annotations can also attach a screenshot. API responses, downloads, event streams, and WebSocket upgrades pass through without body rewriting.
Custom domains
Use a domain registered through TellWang or bring one you already own. Choose whether TellWang should manage its DNS in Cloudflare or leave DNS with your current provider. The managed choice creates or claims the registrable root zone and returns its assigned nameservers. Connect the root, www, and any other subdomain separately; TellWang reuses that one root zone and publishes each exact hostname, so only the root domain's nameservers change. This delegates DNS only and does not transfer registration. The response's zone_domain identifies that root. The external choice returns the exact TXT ownership challenge and direct A record to add. Automatic mode detects Cloudflare DNS, or returns TXT and CNAME records. The edge route and automatic TLS stay off until each hostname verifies.
A connected domain moves with its Site when an owner transfers the Site to another organization, and the live route stays on the same stable Wok id. Exact matching TellWang-managed DNS or registration ownership moves with it. A broader parent DNS zone stays with the source organization when only one of its subdomains moves.
In Lollipop, open Domains under Manage to buy a new domain. Availability is checked first, and the final confirmation shows the exact charge today plus the current yearly renewal estimate. Purchased rows show their registrar expiry date, auto-renew state, and renewal estimate. Connect to site attaches the domain directly when the Project has one Site, asks which Site when it has several, or opens the existing import-or-build flow when it has none. Lollipop publishes the managed DNS records and checks the connection once. A connected row offers Unlink with a confirmation; unlinking stops that Site from serving on the domain but keeps the purchase and DNS records in Lollipop. Manage DNS lists and edits records only for domains bought through Lollipop; an externally registered hostname stays in the separate connected-hostname flow and continues to be managed at its own DNS provider.
Once a custom domain verifies, it becomes the website's canonical host. TellWang aligns generated robots.txt and sitemap.xml, canonical links, and og:url with that origin. Website requests to <wok-id>.tellwang.com permanently redirect to the custom domain with the path and query intact; the platform hostname remains available for stable Wok service endpoints.
# 1. Connect the hostname to the Wok
curl -X PUT https://tellwang.com/v1/woks/$WOK/domains/www.acme.com \
-H "Authorization: Bearer $TELLWANG_KEY"
# → { dns_status:"pending", dns_published, txt_record, cname_record, hint }
# 2. If dns_published=false, add BOTH returned records at your DNS host.
# Then verify once; the server waits for propagation.
curl -X POST https://tellwang.com/v1/woks/$WOK/domains/www.acme.com/verify \
-H "Authorization: Bearer $TELLWANG_KEY" \
-H "Content-Type: application/json" \
-d '{"wait_seconds":120}'
# → { domain, dns_status:"verified", waited_seconds, ... }dns_status:"failed"; follow next_check_after instead of retrying in a loop. TellWang installs the route and manages the Let's Encrypt certificate after ownership verifies.The verified hostname serves the Wok frontend and becomes its canonical website origin. Stable service routes remain available at <wok>.tellwang.com.
TellWang homepage, Shopify store
Keep Shopify's native storefront on Shopify. Serve the homepage at acme.com or www.acme.com from the Wok, then connect shop.acme.com directly to Shopify. This is the pattern Shopify documents when the root domain serves another website. A transparent reverse proxy is not supported by Shopify and can interfere with storefront routing, cart, checkout, accounts, Markets, cookies, TLS, and bot handling. See Shopify's subdomain setup guide.
# Homepage on TellWang
www.acme.com CNAME edge.tellwang.com
# Native storefront on Shopify; keep this record DNS-only
shop.acme.com CNAME shops.myshopify.comAdd shop.acme.com in Shopify Admin under Settings → Domains, complete any ownership record Shopify requests, wait for Shopify to report TLS ready, and make it the Shopify primary domain. Homepage product and checkout links should use absolute https://shop.acme.com/… URLs. Add a navigation link in the Shopify theme back to the TellWang homepage.
If the apex previously served product or collection URLs, a static Wok can keep them working with frontend/_redirects:
/products https://shop.acme.com/collections/all 308
/products/* https://shop.acme.com/products/:splat 308
/collections https://shop.acme.com/collections 308
/collections/* https://shop.acme.com/collections/:splat 308These redirects preserve query parameters such as product variants and campaign attribution. For an SSR Wok, put the same permanent, query-preserving redirects in the app router; frontend/_redirects applies only to static hosting. Leave cart mutations, checkout, account, app, admin, webhook, and API routes on the Shopify hostname. If products must render under the exact homepage hostname, use the Shopify headless migration setup and hand checkout to Shopify instead of proxying the native theme.
TellWang homepage, WooCommerce store
The same gradual transition can keep the native WordPress storefront on shop.acme.com while a Wok serves the homepage. Point that store hostname directly at the WordPress/WooCommerce origin and use absolute links from the Wok. Product, cart, My Account, checkout, payment-plugin, webhook, and WordPress API routes stay on that origin.
The top-level Import workspace can detect a WooCommerce store and capture its public pages as a design reference. Talk to us about a full migration, or see the Import guide.
API reference
POST /v1/woks/{id}/frontend— body{files:{path:content}}, requiresindex.html. Body cap 25 MiB total (5 MiB/file, up to 25000 files — a framework export's many small chunks deploy fine; the 25 MiB aggregate is the real bound, so put large media in a storage bucket). Optional_redirectsrules are applied before the SPA fallback.POST /v1/woks/{id}/appserver/deploy— body is a.tar.gzof a Next.jsoutput:'standalone'bundle (server.jsat the root). Switches the Wok to SSR mode and runs it on a Node server. Cap 250 MiB.POST /v1/woks/{id}/appserver/static— revert an SSR Wok to static file serving.GET /v1/woks/{id}/frontend— list files + sizes.DELETE /v1/woks/{id}/frontend— tear down.PUT /v1/woks/{id}/domains/{domain}— attach a domain and return its TXT ownership challenge plus routing CNAME.POST /v1/woks/{id}/domains/{domain}/verify— wait once for DNS propagation, then install the edge route and TLS.GET /v1/woks/{id}/domains— list attached external domains + dns_status.DELETE /v1/woks/{id}/domains/{domain}— detach.