@nreactive/vite
v0.2.0
Published
Vite plugin + React provider for nreactive — auto-injects the integration script and catches React render errors via an Error Boundary
Downloads
54
Maintainers
Readme
@nreactive/vite
Vite plugin + React provider for nreactive — auto-injects the browser integration script into index.html and catches React render errors via an Error Boundary, feeding both into the nreactive AI error-fix pipeline.
- Plugin: a one-line
nreactive()entry invite.config.tsinjects<script src="https://nreactive.com/integration.js" data-app-id="…">at the top of<head>for bothvite devandvite build. The script captures runtime exceptions, unhandled rejections, fetch + XHR failures,console.error/console.warn, resource load errors, CSP violations, and long tasks. - React provider: a single
<NreactiveProvider>from@nreactive/vite/reactthat wraps your app in an Error Boundary so render-time errors — whichwindow.onerrorcannot see — also reach the dashboard. - The two pieces are deliberately independent. The plugin gets the SDK loaded; the provider wires React into it. Use either, or both.
- Works with Vite 4, 5, and 6 on Node ≥ 20. React 17+ (provider only).
Install
npm install @nreactive/vite
# or: pnpm add @nreactive/vite
# or: yarn add @nreactive/vite
# or: bun add @nreactive/vitereact is an optional peer dependency — only required if you import @nreactive/vite/react.
AI-assisted setup
Paste the prompt below into Claude Code, Cursor, Copilot, or any agent with file-write access. It has enough information to finish the integration end-to-end — the Vite plugin, the React provider, and env wiring — with no manual hand-tuning.
You are adding the
@nreactive/viteSDK to this Vite project.nreactiveis a production error-monitoring service that opens AI-generated pull requests to fix the errors it catches.
- Detect the package manager from the lockfile (
package-lock.json→ npm,pnpm-lock.yaml→ pnpm,yarn.lock→ yarn,bun.lockb→ bun) and install@nreactive/vite.- In
vite.config.ts(or.js), import the default export from@nreactive/viteand add it to thepluginsarray — after@vitejs/plugin-reactif present. The plugin takes no required options.- If the project uses React, wrap the root component in
<NreactiveProvider>from@nreactive/vite/react(typically insrc/main.tsxorsrc/main.jsx, around<App />insidecreateRoot(...).render(...)). Skip this step for non-React Vite apps — the plugin alone is enough.- If the project already includes
<script src="https://nreactive.com/integration.js">inindex.html, REMOVE it — the plugin now injects the same tag automatically and running both would double-fire events.- Add
VITE_NREACTIVE_APP_ID=to.env.example(create it if missing). The user obtains their App ID from https://nreactive.com/dashboard/apps.- Restart the dev server and confirm events appear in the dashboard.
Do not invent additional configuration. Stop and ask if the project doesn't use Vite, or if there's an unusual
index.htmlsetup (e.g. a custom HTML transform that rewrites<head>).
Quick start
vite.config.ts
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import nreactive from "@nreactive/vite";
export default defineConfig({
plugins: [react(), nreactive()],
});The plugin reads the App ID from VITE_NREACTIVE_APP_ID (then falls back to NREACTIVE_APP_ID). You can also pass it explicitly:
nreactive({ appId: "app_ab12cd34ef" });src/main.tsx
import { createRoot } from "react-dom/client";
import { NreactiveProvider } from "@nreactive/vite/react";
import App from "./App";
createRoot(document.getElementById("root")!).render(
<NreactiveProvider>
<App />
</NreactiveProvider>,
);.env
VITE_NREACTIVE_APP_ID=app_ab12cd34efGet your App ID from the nreactive dashboard.
How it works
- The Vite plugin registers a
transformIndexHtmlhook withenforce: "pre"andorder: "pre", so the<script>tag is prepended to<head>before any other plugin's HTML transforms (including@vitejs/plugin-react's refresh shim). The injected tag carriesdata-app-id="…", which the integration script reads to identify the project. If no App ID is resolved the plugin logs a single warning at startup and emits no<script>tag — the build still succeeds, so local prototyping isn't blocked. - The integration script (loaded from
https://nreactive.com/integration.js) installs eight browser capture surfaces —window.onerror,unhandledrejection,fetch,XMLHttpRequest,console.error,console.warn, resource load errors, CSP violations, and long tasks — and exposes a manual API onwindow.__nreactive(capture,flush). <NreactiveProvider>is a thin React Error Boundary aroundchildren. WhencomponentDidCatchfires, the boundary splices the React component stack ontoerror.stackand forwards the error towindow.__nreactive.capture(err, "critical"). Without afallback, the boundary re-throws on the next microtask so React's default overlay (or HMR) still surfaces the error in development.- App ID resolution in the plugin (in order):
appIdoption passed tonreactive({ appId }).process.env.VITE_NREACTIVE_APP_ID.process.env.NREACTIVE_APP_ID.
API
nreactive(options?) — default export
Vite plugin. Pass to the plugins array in vite.config.ts.
interface NreactiveViteOptions {
/**
* Your nreactive App ID. When omitted the plugin reads
* VITE_NREACTIVE_APP_ID, then NREACTIVE_APP_ID.
*/
appId?: string;
/**
* Override the script URL. Defaults to
* "https://nreactive.com/integration.js". Useful only if you
* self-host a mirror.
*/
scriptSrc?: string;
/** Inject only during `vite dev`. Default: false (inject everywhere). */
devOnly?: boolean;
/** Inject only during `vite build`. Default: false (inject everywhere). */
prodOnly?: boolean;
/**
* Extra attributes merged onto the injected <script> tag — useful
* for `nonce`, `crossorigin`, `referrerpolicy`, etc.
*/
attrs?: Record<string, string>;
}<NreactiveProvider> — from @nreactive/vite/react
interface NreactiveProviderProps {
/**
* Override the App ID surfaced via useNreactive(). Almost always
* omitted — the plugin already injects the script tag with the
* right ID.
*/
appId?: string;
/**
* Optional fallback UI rendered after a render error is caught.
* May be a ReactNode or a function (err) => ReactNode. If omitted
* the boundary re-throws on the next microtask so React's default
* overlay / HMR still surfaces the error.
*/
fallback?: ReactNode | ((error: Error) => ReactNode);
/**
* Called after the boundary forwards the error to nreactive.
* Errors thrown from onError are swallowed.
*/
onError?: (error: Error, info: ErrorInfo) => void;
children: ReactNode;
}useNreactive()
interface NreactiveContextValue {
capture: (err: unknown, severity?: "critical" | "error" | "warn") => void;
flush: () => void;
appId: string | undefined;
}"use client";
import { useNreactive } from "@nreactive/vite/react";
export default function ContactButton() {
const { capture } = useNreactive();
return (
<button
onClick={async () => {
try {
await fetch("/api/contact", { method: "POST" });
} catch (err) {
capture(err);
}
}}
>
Contact
</button>
);
}Safe to call outside a <NreactiveProvider> — capture/flush degrade to no-ops if window.__nreactive isn't loaded yet (e.g. during SSR or before the script tag has executed).
Common configurations
Inject only in production builds
nreactive({ prodOnly: true });Useful if you'd rather not see your local errors land on the dashboard. Pair with sendInDevelopment: false semantics on the server side.
CSP nonce
nreactive({
attrs: { nonce: "{{CSP_NONCE}}" },
});Vite leaves attribute values verbatim in the emitted HTML — replace {{CSP_NONCE}} with your server-side template substitution.
Custom fallback UI
<NreactiveProvider
fallback={(err) => (
<div role="alert">
<h1>Something went wrong</h1>
<pre>{err.message}</pre>
</div>
)}
>
<App />
</NreactiveProvider>When you supply a fallback, the boundary stops re-throwing — the user sees your fallback instead of the React overlay.
Why the provider is a superset of the script tag alone
- One source of capture per page. If you keep a hand-rolled
<script src="…/integration.js">inindex.htmland enable the plugin, every event fires twice. Pick one. - The script tag can't catch render errors. React render errors don't bubble to
window.onerror; only an Error Boundary sees them. The provider has one built in. - The provider works without the plugin. If you load the integration script some other way (e.g. via Google Tag Manager), the provider still wires React render errors into
window.__nreactive.captureonce it's available.
If you currently have a manual <script> tag in index.html, remove it when you adopt this package.
Links
- Core SDK:
@nreactive/core - Next.js integration:
@nreactive/next - Express adapter:
@nreactive/express - Fastify adapter:
@nreactive/fastify - Browser script reference: https://nreactive.com/docs/browser
- Full documentation: https://nreactive.com/docs/vite
- Dashboard: https://nreactive.com/dashboard
License
PROPRIETARY. See LICENSE.
