Host & A/B Test Any Page
TagadaPay can host any static HTML page or single-page application and serve it on a fast global CDN (~10ms TTFB). You can then split traffic between variants using weighted or geo-based A/B testing — all through the REST API.Why Host on TagadaPay Instead of Your Own Servers?
| Benefit | Details |
|---|---|
| Edge-fast serving | Pages are served from a global edge network (~10 ms TTFB). A/B variant selection happens at the edge too — no extra round-trip to an origin server, so visitors never feel the split. |
| Same-URL A/B testing | Both variants live on the exact same URL. The routing engine picks the right one transparently. This is critical for ad campaigns, email links, and SEO — you don’t need separate URLs or client-side redirect hacks. |
| Custom domains & routing in one click | Bring your own domain, point a CNAME, verify via API, done. TagadaPay handles TLS, routing, and CDN caching automatically. No nginx configs, no Cloudflare rules, no load balancers. |
| Free hosting for TagadaPay users | Hosting is included at no extra cost when you use TagadaPay. No bandwidth bills, no storage fees, no infra to maintain. |
Use Cases
| Use case | Example |
|---|---|
| Landing page testing | Test two headline variants to see which converts better |
| Geo-targeted content | Show a French page to EU visitors, English to US visitors |
| Gradual rollouts | Send 10% of traffic to a new design before going 100% |
| External SPAs | Host a React/Vue/Svelte app without managing your own infra |
- A unique URL on
*.cdn.tagadapay.com(or your own domain) - Instant global delivery via edge CDN
- Built-in A/B split testing (weighted or geo) on the same URL
- Sticky sessions so returning visitors see the same variant
Prerequisites
TagadaPay account
TagadaPay account
Sign up at app.tagadapay.com and create a store.
API key
API key
Go to Settings → API Keys in your dashboard and generate one. It looks like
xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.curl (or any HTTP client)
curl (or any HTTP client)
All examples use
curl. You can use Postman, httpie, or any language’s HTTP library.The 3-Step Flow
Every deployment follows the same pattern:| Step | What it does |
|---|---|
| Deploy | Uploads your files (HTML, CSS, JS, images) to blob storage |
| Instantiate | Creates a running instance of that deployment for a store |
| Mount | Binds the instance to a URL so visitors can access it |
Step 1 — Deploy a Page
Create a simple HTML file and deploy it via the API. Assets are sent as base64-encoded strings.Step 2 — Instantiate
An instance is a “live copy” of a deployment, bound to a specific store. You can create multiple instances of the same deployment with different configurations.instanceId from the response.
Instance Config
Theconfig object is optional but powerful. Whatever you pass here is injected into the served HTML as window.__TAGADA_PLUGIN_CONFIG__, making it available to your JavaScript at runtime. This lets you deploy one set of files and customize behavior per-instance without redeploying.
You don’t have to read
window.__TAGADA_PLUGIN_CONFIG__ manually. The TagadaPay Plugin SDK reads it for you and exposes it via tgd.config. Using the SDK is the recommended approach — it also gives you session management, analytics, and funnel navigation out of the box. Reading the global directly is perfectly valid if you want zero dependencies, but for most use cases the SDK is simpler.Additional globals like
window.__TAGADA_STORE_ID__ and window.__TAGADA_ACCOUNT_ID__ (and matching x-plugin-* meta tags) are always injected regardless of the config you pass.| Config field | Purpose |
|---|---|
theme, colors | Brand customization without redeploying assets |
headline, cta | Copy testing across multiple instances |
locale, currency | Localization per region (combine with geo A/B) |
featureFlags | Gradual feature rollout |
analyticsId | Per-store tracking IDs |
Step 3 — Mount
Mounting binds your instance to a hostname so it becomes reachable by visitors.routeId from the response — you’ll need it if you set up A/B testing.
Your page is now live at:
Set Up A/B Testing
You can split traffic on any mounted route. TagadaPay supports two split types:| Type | How it works |
|---|---|
| weighted | Split by percentage (e.g. 50/50, 90/10) |
| geo | Split by visitor country (ISO country codes) |
Create a Second Variant
A variant is just another instance. There are two ways to create one:- Different deployment (different files)
- Same deployment, different config
Deploy entirely different HTML/CSS/JS (Step 1), then instantiate it (Step 2). Each variant has its own build assets — useful when the pages are structurally different (e.g. a completely redesigned layout vs. the original).You’ll get a separate
pluginId, deploymentId, and instanceId for the variant.You do not mount the second variant separately. Both variants share the same URL — the split testing system decides which one to serve.
Configure the Split
Call the split endpoint with therouteId from Step 3 and both instance IDs:
- Geo-based
- Weighted (percentage)
Route visitors to different variants based on their country.Visitors from unlisted countries fall back to the first instance.
How Sticky Sessions Work
When a visitor hits a split route for the first time, TagadaPay picks a variant and stores the choice in a sticky session cookie (tgd-session-id). On subsequent visits within stickyDuration seconds (default: 7 days), the same variant is served.
This ensures a consistent experience — a visitor won’t flip between variants mid-session.
Update a Variant
To push a new version of a variant, deploy with"overwrite": true:
Deploying a Full SPA
TagadaPay can host any single-page application (React, Vue, Svelte, etc.). Build your app, then deploy all output files:Advanced: Large File Uploads (> 4 MB)
The
inlineAssets method shown above sends base64-encoded files inside the JSON body. This works well for small pages, but serverless functions have a ~4.5 MB body limit. If your SPA build output is larger — bundled JS, images, fonts — you need the two-step blob upload flow instead.How the blob upload flow works
How the blob upload flow works
Instead of embedding assets in the request body, you:
- Upload a ZIP of your build output to TagadaPay’s blob storage, which supports multipart uploads up to 50 MB.
- Deploy from the blob URL — pass the returned URL to the deploy endpoint, which downloads and extracts the ZIP server-side.
Step-by-step with curl
Step-by-step with curl
Get an upload token
The upload token endpoint implements a client upload protocol. You need to call it twice: once to get a token, then once more to confirm completion. In practice, use the
@vercel/blob client library — it handles both calls for you.Deploy from the blob URL
Now pass the blob URL to the V2 deploy endpoint using the The server downloads the ZIP, extracts all files, and uploads each one to blob storage — exactly like
zipUrl parameter instead of inlineAssets:inlineAssets, but without the body size limit.When to use which method
When to use which method
| Method | Max size | Best for |
|---|---|---|
inlineAssets (base64 in JSON) | ~4 MB total payload | Single HTML pages, small sites, quick tests |
zipUrl (blob upload) | 50 MB | Full SPAs, sites with images/fonts, production builds |
Custom Domain
By default your page is served on*.cdn.tagadapay.com. You can mount it on your own domain instead using the Domains API.
Register the domain
Call the domains API to add your domain to TagadaPay. This registers it with the edge network and returns a verification token.Response:Save the
id — you’ll use it to verify.Configure DNS
Add the required DNS records at your registrar. You need a CNAME pointing to
Wait for DNS propagation (usually a few minutes, can take up to 48h).
cname.vercel-dns.com:| Type | Name | Value |
|---|---|---|
| CNAME | landing | cname.vercel-dns.com |
Verify the domain
Once DNS has propagated, call the verify endpoint:A successful response looks like:
API Reference
| Endpoint | Method | Description |
|---|---|---|
/api/public/v1/plugins/v2/deploy | POST | Upload files and create a deployment (inlineAssets or zipUrl) |
/api/public/v1/plugins/generate-upload-token | POST | Get a blob upload token for large files (multipart, up to 50 MB) |
/api/public/v1/plugins/v2/instantiate | POST | Create a live instance from a deployment |
/api/public/v1/plugins/v2/mount | POST | Bind an instance to a URL (hostname or custom domain) |
/api/public/v1/plugins/v2/split | POST | Configure A/B testing on a route |
/api/public/v1/domains/add | POST | Register a custom domain |
/api/public/v1/domains/verify | POST | Verify DNS configuration |
/api/public/v1/domains/list | POST | List all custom domains |
/api/public/v1/domains/remove | POST | Remove a custom domain |
Authorization: Bearer YOUR_API_KEY and Content-Type: application/json.
Troubleshooting
404 after mounting
404 after mounting
Make sure the
hostname in the mount request matches the URL you’re visiting.
Format: {slug}--{storeId}.cdn.tagadapay.comDouble-check that basePath is / and matcher is /.A/B test always shows the same variant
A/B test always shows the same variant
Sticky sessions may be pinning you to one variant. Clear your cookies or use incognito mode to get a fresh session. For geo testing, the system reads the visitor’s country from the edge network — make sure you’re testing from the expected country or use a VPN.
Assets (CSS/JS) return 404
Assets (CSS/JS) return 404
Ensure each asset’s
path in inlineAssets matches the path referenced in your HTML.
For example, if your HTML has <script src="/assets/app.js">, the asset path must be /assets/app.js.Deploy fails with 'Plugin name is required'
Deploy fails with 'Plugin name is required'
The
manifest object requires at minimum: name, version, and pages (array with at least one entry). Each page needs id, path (starting with /), and name.