SDK — Vite
Install `@layers/client` in a Vite SPA. `import.meta.env` env vars, dev-server proxy, optional `vite.config.ts` integration.
The Layers SDK works in any Vite-built SPA via @layers/client. Vite's build is build-time-only — there is no runtime env, so every Layers config that varies per environment must be a VITE_* env var baked at build.
Install
npm i @layers/clientInitialize
In your app entrypoint (src/main.tsx):
import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';
import { LayersClient } from '@layers/client';
import App from './App';
const layers = new LayersClient({
apiKey: 'unused-but-required-by-type',
appId: import.meta.env.VITE_LAYERS_APP_ID,
environment: import.meta.env.MODE === 'production' ? 'production' : 'development',
});
await layers.init();
createRoot(document.getElementById('root')!).render(
<StrictMode>
<App layers={layers} />
</StrictMode>,
);Pass the client through context or a single shared instance — there is no <LayersProvider> package today. The pattern from the Next.js guide (a tiny React context wrapper) translates directly.
Auto-screen on route changes
If you use TanStack Router, React Router, or any router that exposes a "current path" hook, fire layers.screen() on every change:
import { useEffect } from 'react';
import { useLocation } from 'react-router-dom';
function PageTracker({ layers }) {
const { pathname } = useLocation();
useEffect(() => {
layers.screen(pathname).catch(() => {});
}, [pathname]);
return null;
}For React Router specifically, see the dedicated React Router guide.
Environment variables
| Var | Purpose | Where it must live |
|---|---|---|
VITE_LAYERS_APP_ID | The SDK app id from POST /sdk-apps. | .env, .env.production. Also in app/Dockerfile ARG/ENV if you Dockerize. |
VITE_LAYERS_INGEST_ENDPOINT | Override the default ingest URL — for custom domain. | Same as above. |
Vite SPAs inline VITE_* at build time. After changing the value, you must rebuild — restarting the dev server is not enough on a previously-built bundle.
Dev-server proxy snippet
If you've configured a custom domain for production but want to hit https://in.layers.com in dev, proxy through Vite's dev server to avoid CORS:
import { defineConfig } from 'vite';
export default defineConfig({
server: {
proxy: {
'/_layers/events': {
target: 'https://in.layers.com',
changeOrigin: true,
rewrite: (p) => p.replace(/^\/_layers\/events/, '/events'),
},
},
},
});Then init with:
const layers = new LayersClient({
appId: import.meta.env.VITE_LAYERS_APP_ID,
baseUrl: import.meta.env.MODE === 'production'
? 'https://in.layers.com'
: 'http://localhost:5173/_layers',
apiKey: 'unused',
});SSR with Vite
Server-rendered Vite apps (e.g. via vite-ssr, Astro's Vite mode) should treat the SDK identically to Next.js — initialize only on the client, never on the server. The package gracefully no-ops on a missing window in some flows, but the only safe pattern is to gate on typeof window !== 'undefined' (or wrap in a client-only component).
Verifying the install
curl -X POST https://api.layers.com/v1/projects/$PROJECT_ID/sdk-apps/$APP_ID/verify-tracking \
-H "Authorization: Bearer $LAYERS_API_KEY"See verify-tracking.