Sentry Zustand Middleware
sentry-zustand-middleware is a specialized middleware for Zustand stores designed to automatically log state changes and actions to Sentry. This package is currently at version 4.3.0 and typically follows the release cycles of its peer dependencies, Zustand and Sentry, to ensure compatibility. Its core function is to capture the state snapshots and the actions that modify them, providing enhanced debugging capabilities and visibility into application state flow during error reporting. A key differentiator is its optional `stateTransformer` function, which allows developers to clean, filter, or obfuscate sensitive data from the Zustand state before it is sent to Sentry, preventing oversharing of private information. It provides a direct integration without manual Sentry calls within every action or state update.
Common errors
-
TypeError: Sentry is not initialized
cause The Sentry SDK's `init` function was not called before the `sentry-zustand-middleware` attempted to send an event.fixCall `Sentry.init({ dsn: 'YOUR_DSN' })` at the very beginning of your application's lifecycle, typically in `main.ts` or `App.tsx`. -
Error: Middleware cannot be found for 'zustand'
cause Likely due to mismatched Zustand versions or incorrect import paths for the middleware, especially when mixing CJS and ESM environments.fixVerify that your `zustand` and `sentry-zustand-middleware` packages are compatible and that you are using the correct import syntax (ESM `import` statements) throughout your project. -
Property 'bears' does not exist on type 'BearState'
cause This is a TypeScript error indicating a mismatch between the state interface defined for `create` and the actual state object being used or returned.fixReview your `BearState` interface and ensure all properties and methods are correctly defined and that the initial state and `set` calls conform to this interface.
Warnings
- breaking This middleware requires specific peer dependency versions for Sentry and Zustand. Ensure your project's `@sentry/browser` is `>= 7.87.0` and `zustand` is `>= 4.1.3` to avoid compatibility issues.
- gotcha Sentry must be initialized BEFORE the `sentry-zustand-middleware` is used. If Sentry is not initialized, the middleware will not send events, and you may not see errors, potentially leading to silent failures.
- gotcha By default, the middleware logs the entire Zustand state. If your state contains sensitive user information, tokens, or large objects, this data will be sent to Sentry. This can lead to privacy breaches or excessive Sentry usage.
- gotcha Actions are logged with the name provided as the third argument to the `set` function (e.g., `set(..., false, 'actionName')`). If no action name is provided, Sentry might log a generic 'Anonymous' action, making debugging harder.
Install
-
npm install sentry-zustand-middleware -
yarn add sentry-zustand-middleware -
pnpm add sentry-zustand-middleware
Imports
- sentryMiddleware
const sentryMiddleware = require('sentry-zustand-middleware');import sentryMiddleware from 'sentry-zustand-middleware';
- SentryZustandMiddlewareOptions
import type { SentryZustandMiddlewareOptions } from 'sentry-zustand-middleware'; - create
import { create } from 'zustand';import create from 'zustand';
Quickstart
import create from 'zustand';
import sentryMiddleware from 'sentry-zustand-middleware';
// Ensure Sentry is initialized elsewhere in your application entry point
// For example:
// import * as Sentry from '@sentry/browser';
// Sentry.init({ dsn: process.env.SENTRY_DSN ?? '' });
interface BearState {
bears: number;
increase: (by: number) => void;
decrease: (by: number) => void;
logSomething: (message: string) => void;
}
const useStore = create<BearState>()(
sentryMiddleware((set) => ({
bears: 0,
increase: (by) => {
set((state) => ({ bears: state.bears + by }), false, 'increaseBears');
},
decrease: (by) => {
set((state) => ({ bears: state.bears - by }), false, 'decreaseBears');
},
logSomething: (message) => {
// This action will also be logged by the middleware
console.log(message);
}
})),
);
// Example usage (ensure Sentry is initialized for actual logging)
const store = useStore.getState();
store.increase(5);
store.decrease(2);
console.log('Current bears:', useStore.getState().bears);