— React SDK

React SDK (sdk-react)

Provider and hook ergonomics for React apps. Wraps the browser SDK so you get capture functions anywhere in your component tree without passing props down.

Install

pnpm add @emit-vision/sdk-react
npm install @emit-vision/sdk-react

Wrap your app with EmitVisionProvider

Place <EmitVisionProvider> at the root of your app so every component has access to the SDK. Pass your API key and deployment metadata here — this is the one initialization point.

import { EmitVisionProvider } from "@emit-vision/sdk-react";

export function App({ children }: { children: React.ReactNode }) {
  return (
    <EmitVisionProvider
      apiKey={process.env.NEXT_PUBLIC_EMIT_VISION_API_KEY}
      environment="production"
      release="[email protected]"
    >
      {children}
    </EmitVisionProvider>
  );
}

Use the hook in any component

Call useEmitVision() to get { captureEvent, captureError, identify, flush }. The hook is safe to call in any client component inside the provider.

import { useEmitVision } from "@emit-vision/sdk-react";

function SaveButton() {
  const { captureEvent } = useEmitVision();

  return (
    <button
      onClick={() => captureEvent("button_click", { label: "Save" })}
    >
      Save
    </button>
  );
}

Full working example

Provider at the root layout, hook in a leaf component that also identifies the user on mount:

// app/layout.tsx (or your root component)
import { EmitVisionProvider } from "@emit-vision/sdk-react";

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <EmitVisionProvider
      apiKey={process.env.NEXT_PUBLIC_EMIT_VISION_API_KEY}
      environment={process.env.NODE_ENV}
      release={process.env.NEXT_PUBLIC_APP_VERSION ?? "dev"}
    >
      {children}
    </EmitVisionProvider>
  );
}

// components/UserGreeting.tsx
"use client";
import { useEffect } from "react";
import { useEmitVision } from "@emit-vision/sdk-react";

export function UserGreeting({ userId }: { userId: string }) {
  const { identify, captureEvent } = useEmitVision();

  useEffect(() => {
    identify(userId);
    captureEvent("page_view", { route: "/dashboard" });
  }, [userId, identify, captureEvent]);

  return <p>Welcome back!</p>;
}

Migration from sdk-js

If you were calling init() directly from @emit-vision/sdk-js:

  • Remove the init() call — the provider replaces it.
  • Keep calling captureEvent(), captureError(), identify(), and flush() the same way, now via the hook.
  • Do not call both init() and mount the provider — that resets the internal queue twice.