Local development
Run your Amba-powered app on localhost — what works in vite, next dev, expo, and React Native, and the one gotcha with magic-link callbacks.
The Amba browser SDK is designed to work in local development out of the box. Browser CORS preflight from http://localhost:* (or http://127.0.0.1:*, or http://[::1]:*) is allowed against https://api.amba.dev for every Amba project — no extra config, no proxy, no signed certificate.
This page covers what works, what doesn't, and the workarounds for the cases that don't.
What works
@layers/amba-webundervite dev,next dev,react-scripts start,parcel,webpack-dev-server, and any framework that serves onlocalhostover HTTP. Every wrapped namespace (auth,events,entitlements,config,collections,flags,storage) goes through the same fetch path and the same CORS rules.@layers/amba-expoundernpx expo start. Expo runs your app in the Expo Go shell (or a development build on a device). API calls go out from the device's network — no browser CORS involved.@layers/amba-react-nativeundernpx react-native start. Native fetch, no CORS.@layers/amba-nodeundernode --watch,tsx watch,nodemon, or any reload-on-save runner. Server-side, no CORS.
Point apiUrl at production from your local environment:
Everything tracked, fetched, or mutated during local dev hits the same project as your deployed app. If you don't want that — see Use a separate dev project below.
What doesn't work (and the workaround)
Magic-link sign-in callbacks
Magic-link emails ship the verify URL pinned to your project's deployed app URL (https://your-app.app.amba.host or your verified custom domain). Clicking a link from a localhost run lands you in the deployed app, not your local dev server.
Workarounds:
- Use email/password or anonymous auth during local dev. Magic-link is an intent verification flow — testing it on localhost is the same as testing it on production, since the verify URL is project-scoped.
- Forward the verify URL to localhost. Click the link, then copy the
?token=…query param onto your localhost URL:http://localhost:3000/auth/callback?token=…. The token validates server-side; the redirect URL never reaches the API.
Cross-origin cookies
The SDK uses header authentication, not cookies — X-Api-Key on every request, Authorization: Bearer <session_token> after sign-in. So cross-origin cookie restrictions don't apply. If you're seeing cookie warnings in dev tools, those are from your own app, not the SDK.
Service workers + offline mode
If your local dev server doesn't run a service worker (vite dev / next dev usually don't), the SDK's offline event queue is still active but uses localStorage exclusively. Events written while you're disconnected from the network will be flushed on reconnect.
Use a separate dev project
Keep your live tenant clean by running local dev against a second Amba project — same SDK code, different keys, separate database.
-
Sign up a sandbox project:
npx @layers/amba init --sandbox(or via the agentic flow:amba_developer_signupthenamba_projects_createwithtier: "sandbox"). -
Put its keys in
.env.local: -
Reset the sandbox at any time with the SDK helper:
This wipes every user, event, and collection row in the sandbox tenant — the project itself stays, so your keys keep working. Only callable against sandbox-tier projects; production tenants reject it with
NOT_SANDBOX_TIER.
Security model recap
The SDK is always authenticated by X-Api-Key (your project's clientKey). The clientKey is browser-public by design — it's safe to ship in JavaScript bundles, embed in mobile apps, or paste into a dev environment. Every client request also carries either an anonymous device ID or, after sign-in, a Bearer session token.
CORS is defense-in-depth, not the security boundary. We allow localhost origins on the API because letting any origin with a valid clientKey call the API is the same posture as allowing every *.app.amba.host customer-app subdomain, which we already accept. The boundary that matters is the clientKey + Bearer token combination, not the request Origin header.