Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.velt.dev/llms.txt

Use this file to discover all available pages before exploring further.

Route Velt SDK traffic through reverse proxies on your own domain. This keeps all Velt-related network calls branded to your infrastructure and satisfies strict network policies that prohibit direct connections to third-party services.

Why use a proxy?

  • Egress control — route all Velt SDK traffic through infrastructure you own and monitor.
  • Compliance — keep third-party endpoints off your app’s public egress rules.
  • Custom domains — serve backend traffic from subdomains under your own brand.
  • Geo-routing — place the proxy closer to your users than the nearest upstream region.

How it works

The Velt SDK talks to several backend services. You can proxy any combination of them by setting the matching field on proxyConfig:
ServiceproxyConfig fieldUpstream
CDN — the SDK bundle itselfcdnHostcdn.velt.dev
API — Velt API callsapiHostapi.velt.dev
Persistence Database — Velt v2 databasev2DbHostfirestore.googleapis.com
Ephemeral Database — Velt realtime databasev1DbHost*.firebaseio.com
Storage — file/attachment storagestorageHostfirebasestorage.googleapis.com
Auth — authentication token endpointsauthHostidentitytoolkit.googleapis.com + securetoken.googleapis.com
┌─────────┐     ┌────────────────────────┐     ┌──────────────────────┐
│ Browser │ ──▶ │  your proxy domains:   │ ──▶ │ Velt SDK backend     │
│ (Velt   │     │   auth-proxy.*         │     │  services (upstream) │
│  SDK)   │     │   v2db-proxy.*         │     │                      │
│         │     │   v1db-proxy.*         │     │                      │
│         │     │   storage-proxy.*      │     │                      │
└─────────┘     └────────────────────────┘     └──────────────────────┘
                    (Cloudflare / nginx)
See ProxyConfig reference for the full type definition.

Quick start

Point the Velt SDK at your proxy subdomains. Each field is optional — omit any host you don’t proxy and the SDK will talk to the default upstream directly.
<VeltProvider apiKey="YOUR_API_KEY" config={{
  proxyConfig: {
    cdnHost:     'https://cdn-proxy.yourdomain.com',
    apiHost:     'https://api-proxy.yourdomain.com',
    v2DbHost:    'https://v2db-proxy.yourdomain.com',
    v1DbHost:    'https://v1db-proxy.yourdomain.com',
    storageHost: 'https://storage-proxy.yourdomain.com',
    authHost:    'https://auth-proxy.yourdomain.com',
    forceLongPolling: false,
  },
}}>
  <App />
</VeltProvider>
Need to deploy the proxy server itself? See Deploy the proxy server for Cloudflare Workers and nginx walkthroughs. For per-host details (such as how the SDK rewrites RTDB hosts when v1DbHost is set), see Configure each service.

Configure each service

Reference for each proxyConfig.* field. Use this section when you only proxy a subset of services or need the per-host implementation notes.

cdnHost

Routes the Velt SDK bundle (the JS file) through your proxy. To serve the Velt SDK via your own proxy server (e.g., nginx) instead of Velt’s servers, provide your proxy’s base URL.
  • Velt automatically appends /lib/sdk@[VERSION_NUMBER]/velt.js to your proxyConfig.cdnHost to determine the full URL for fetching the SDK.
    • If proxyConfig.cdnHost is https://cdn.yourdomain.com, the SDK will be loaded from https://cdn.yourdomain.com/lib/sdk@[VERSION_NUMBER]/velt.js.
  • Your proxy server must be configured to forward requests from [your_proxyDomain] to https://cdn.velt.dev without modifying headers or content.
<VeltProvider 
  config={{
    proxyConfig: {
      cdnHost: 'https://cdn.yourdomain.com'
    }
  }}
></VeltProvider>  

apiHost

Routes Velt API calls through your proxy. To serve the Velt APIs via your own proxy server instead of Velt’s servers, provide your proxy’s base URL using proxyConfig.apiHost.
  • Your proxy server should forward requests from your proxy host to https://api.velt.dev without modifying headers or content.
<VeltProvider
  config={{
    proxyConfig: {
      apiHost: 'https://api.yourdomain.com',
    },
  }}
></VeltProvider>

v2DbHost

Routes Persistence Database (Velt v2 database) traffic through your proxy. Set proxyConfig.v2DbHost. This replaces firestore.googleapis.com for all persistence requests.
  • Your proxy server should forward requests to firestore.googleapis.com without modifying headers or content.
<VeltProvider
  config={{
    proxyConfig: {
      v2DbHost: 'https://v2db-proxy.yourdomain.com',
    },
  }}
></VeltProvider>

v1DbHost

Routes Ephemeral Database (Velt v1 database) traffic through your proxy. Set proxyConfig.v1DbHost. This replaces the firebaseio.com domain in all RTDB URLs.
  • Your proxy server should forward requests to *.firebaseio.com without modifying headers or content.
When v1DbHost is set, the SDK host-locks RTDB by overriding the Firebase SDK’s internal host property setter. This prevents Firebase’s handshake from redirecting traffic to a shard server (s-gke-*.firebaseio.com), keeping all RTDB requests on your proxy domain for the lifetime of the connection.
<VeltProvider
  config={{
    proxyConfig: {
      v1DbHost: 'https://v1db-proxy.yourdomain.com',
    },
  }}
></VeltProvider>

storageHost

Routes File Storage (file attachments, recordings) traffic through your proxy. Set proxyConfig.storageHost. This replaces firebasestorage.googleapis.com.
  • Your proxy server should forward requests to firebasestorage.googleapis.com without modifying headers or content.
<VeltProvider
  config={{
    proxyConfig: {
      storageHost: 'https://storage-proxy.yourdomain.com',
    },
  }}
></VeltProvider>

authHost

Routes Auth traffic through your proxy. Set proxyConfig.authHost. This replaces both identitytoolkit.googleapis.com and securetoken.googleapis.com.
  • Your proxy server should forward requests to both identitytoolkit.googleapis.com and securetoken.googleapis.com based on the request path, without modifying headers or content.
The SDK caches the auth proxy host in localStorage during initConfig(). On subsequent page loads, the cached value is applied synchronously before Auth can fire an internal token refresh, ensuring the refresh request goes through your proxy rather than directly to Google.
<VeltProvider
  config={{
    proxyConfig: {
      authHost: 'https://auth-proxy.yourdomain.com',
    },
  }}
></VeltProvider>

Deploy the proxy server

Deploy a reverse proxy in front of the Velt SDK’s backend services so all Velt traffic flows through infrastructure you own. The recipes below cover the four services most customers need to proxy — Auth, v2Db, v1Db, and Storage — on Cloudflare Workers or nginx.
cdnHost and apiHost are not covered by these recipes. Contact Velt support if you need to proxy the SDK CDN or the Velt API.
You’ll deploy four proxy endpoints — one per service — under subdomains you control, then point the Velt SDK at them via proxyConfig (see Quick start). Routing notes by service
ServiceUpstreamRouting notes
Authsecuretoken.googleapis.com + identitytoolkit.googleapis.comPath-based: /v1/token → token-refresh upstream, else → identity upstream
v2Dbfirestore.googleapis.comStraight passthrough
v1Db*.firebaseio.com (dynamic)Upstream host picked per-request from the ?ns= query param. WebSocket upgrade required.
Storagefirebasestorage.googleapis.comStraight passthrough
Pick your platform
PlatformBest forSetup time
Cloudflare WorkersEdge-distributed, zero infra~15 min
nginxSelf-hosted, full control, existing nginx infrastructure~45 min
All recipes below use the open-source velt-js/velt-proxy-server repo, which ships ready-to-deploy configs for Cloudflare Workers and nginx.
Skip the manual setup with Claude Code. Clone velt-js/velt-proxy-server, open it in Claude Code, and paste this prompt:
I need to route my Velt SDK traffic through my own infrastructure. Can you help me set this up?
The repo ships with a CLAUDE.md that teaches Claude how to wire everything up. Claude will ask for your four proxy subdomains (auth-proxy, v2db-proxy, v1db-proxy, storage-proxy), pick a platform (Cloudflare or nginx), and generate the deployment configuration.

Cloudflare Workers

1

Create four proxy subdomains

Create CNAME records for auth-proxy, v2db-proxy, v1db-proxy, and storage-proxy under a domain you control, and attach them to your Cloudflare zone.
2

Deploy the Workers

Each service has its own Worker in the cloudflare/ folder of the velt-js/velt-proxy-server repo. Deploy all four with Wrangler:
cd cloudflare/auth-proxy    && wrangler deploy && cd ..
cd v2db-proxy               && wrangler deploy && cd ..
cd v1db-proxy               && wrangler deploy && cd ..
cd storage-proxy            && wrangler deploy && cd ..
Then bind each Worker to its subdomain via Cloudflare dashboard → Workers & Pages → Settings → Triggers → Add Custom Domain. See the Cloudflare README for the full walkthrough.
3

Route Auth by path

Auth splits on path: /v1/token and /v2/token go to the token-refresh upstream, everything else goes to identity. The Worker handles this with a simple path check:
// auth-proxy.* handler (abbreviated)
if (url.pathname.startsWith('/v1/token') || url.pathname.startsWith('/v2/token')) {
  url.hostname = 'securetoken.googleapis.com';
} else {
  url.hostname = 'identitytoolkit.googleapis.com';
}
4

Rewrite v1Db upstream from ?ns=

v1Db requests carry the Firebase namespace in the ?ns= query param. The Worker rewrites the upstream Host to the shard that owns that namespace, and special-cases the Upgrade: websocket header so RTDB streams survive:
// v1db-proxy.* handler (abbreviated)
const ns = url.searchParams.get('ns');
if (!ns) return new Response('Missing ns parameter', { status: 400 });

url.hostname = `${ns}.firebaseio.com`;

// Forward the raw Request on WebSocket upgrades so the stream survives
if (request.headers.get('Upgrade') === 'websocket') {
  return fetch(new Request(url, request));
}
5

Verify

From any machine, confirm the proxies respond:
curl -I https://auth-proxy.yourdomain.com/
curl -I https://v2db-proxy.yourdomain.com/
You should see upstream response headers (2xx/4xx are both fine — the proxy is live).
6

Configure the Velt SDK

Point the Velt SDK at your proxy subdomains using the Quick start snippet. WebSockets are enabled by default, so no extra SDK configuration is required.

nginx

The nginx/ folder of the velt-js/velt-proxy-server repo ships a Docker Compose setup with one conf.d/*.conf file per service. The snippets below summarize what each config does — see the nginx README for the full walkthrough.
1

Prereqs

nginx ≥ 1.18 (1.25+ for the http2 on; directive used in the configs) built with ngx_http_proxy_module and WebSocket support, or Docker. TLS certificates covering all four subdomains (a wildcard *.yourdomain.com from Let’s Encrypt is the simplest option).
2

Route Auth by path

Auth is path-based. Inside the auth-proxy.yourdomain.com server block, route /v1/token to the token-refresh upstream and everything else to identity. The proxy_ssl_* directives are required so the upstream TLS handshake uses the correct SNI:
location /v1/token {
  proxy_pass https://securetoken.googleapis.com;
  proxy_set_header Host securetoken.googleapis.com;
  proxy_ssl_server_name on;
  proxy_ssl_name securetoken.googleapis.com;
}

location / {
  proxy_pass https://identitytoolkit.googleapis.com;
  proxy_set_header Host identitytoolkit.googleapis.com;
  proxy_ssl_server_name on;
  proxy_ssl_name identitytoolkit.googleapis.com;
}
3

Dynamic upstream for v1Db

v1Db needs the upstream host picked per-request from ?ns=. Three things are required: a resolver directive (nginx needs runtime DNS for dynamic hostnames), input validation on ?ns=, and the WebSocket upgrade headers so RTDB streams open:
server {
  server_name v1db-proxy.yourdomain.com;

  # Required for dynamic upstream hostnames
  resolver 8.8.8.8 1.1.1.1 valid=300s;
  resolver_timeout 5s;

  location / {
    # Reject malformed ns values before interpolating into the hostname
    if ($arg_ns !~ "^[a-z0-9-]+$") {
      return 400 "Invalid or missing ns parameter\n";
    }

    set $v1db_host "$arg_ns.firebaseio.com";

    proxy_pass https://$v1db_host;
    proxy_set_header Host $v1db_host;
    proxy_ssl_server_name on;
    proxy_ssl_name $v1db_host;

    # WebSocket upgrade — required for real-time listeners
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
  }
}
4

Passthrough for v2Db and Storage

v2Db and Storage are straight passthroughs. Use one server block each with proxy_pass pointing at the upstream and proxy_set_header Host set to the upstream hostname. See conf.d/v2db-proxy.conf and conf.d/storage-proxy.conf for the full server blocks (including SNI, timeouts, and client_max_body_size for uploads).
5

Verify

curl -I https://auth-proxy.yourdomain.com/
curl -I https://v2db-proxy.yourdomain.com/
6

Configure the Velt SDK

Point the Velt SDK at your proxy subdomains using the Quick start snippet.

Advanced

Subresource Integrity (SRI)

To ensure the integrity of the Velt SDK, especially when served via a proxy, Velt leverages Subresource Integrity (SRI). SRI is a security feature that enables browsers to verify that resources they fetch (for example, from a CDN or your proxy server) are delivered without unexpected manipulation.
  • Default: false
<VeltProvider apiKey='YOUR_API_KEY' config={{
  integrity: true,
}}>
</VeltProvider>

Force long polling

Some corporate proxies and load balancers don’t support WebSocket upgrades. If your proxy is one of them, set forceLongPolling: true to force the persistence and ephemeral database connections to use long-polling instead of WebSockets.
  • Default: false
<VeltProvider apiKey='YOUR_API_KEY' config={{
  proxyConfig: {
    forceLongPolling: true,
  },
}}>
</VeltProvider>