Layers

SDK — Vite

Install `@layers/client` in a Vite SPA. `import.meta.env` env vars, dev-server proxy, optional `vite.config.ts` integration.

View as Markdown

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/client

Initialize

In your app entrypoint (src/main.tsx):

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

VarPurposeWhere it must live
VITE_LAYERS_APP_IDThe SDK app id from POST /sdk-apps..env, .env.production. Also in app/Dockerfile ARG/ENV if you Dockerize.
VITE_LAYERS_INGEST_ENDPOINTOverride 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:

vite.config.ts
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.

See also

On this page