Redux Integration

(Available in version 5.20.0 and above)

Redux support is included in the @sentry/react package since version 5.20.0. To apply Sentry to Redux, use Sentry.createReduxEnhancer at the same place that you initialize your Redux store.

Copied
import { createStore, compose } from "redux";
import * as Sentry from "@sentry/react";

// ...

const sentryReduxEnhancer = Sentry.createReduxEnhancer({
  // Optionally pass options listed below
});

const store = createStore(rootReducer, sentryReduxEnhancer);

// ...

If you have other enhancers or middleware such as thunk:

Copied
const store = createStore(
  rootReducer,
  compose(applyMiddleware(thunk), sentryReduxEnhancer)
);

Normalization Depth

By default Sentry SDKs normalize any context to a depth of 3, which in the case of sending Redux state you probably will want to increase that. You do so by passing normalizeDepth to the Sentry.init call:

Copied
Sentry.init({
  dsn: "https://examplePublicKey@o0.ingest.sentry.io/0",
  normalizeDepth: 10, // Or however deep you want your state context to be.
});

Redux Enhancer Options

Pass an options object as the first parameter to Sentry.createReduxEnhancer to configure it.

actionTransformer (Function)
Used to remove sensitive information from actions. The first parameter passed to the function is the Redux action. Return null to not send the action to Sentry. By default we send all actions.

Copied
const sentryReduxEnhancer = Sentry.createReduxEnhancer({
  actionTransformer: action => {
    if (action.type === "GOVERNMENT_SECRETS") {
      // Return null to not log the action to Sentry
      return null;
    }
    if (action.type === "SET_PASSWORD") {
      // Return a transformed action to remove sensitive information
      return {
        ...action,
        password: null,
      };
    }

    return action;
  },
});

stateTransformer (Function)
Used to remove sensitive information from state. The first parameter passed to the function is the Redux state. Return null to not attach the state to events sent to Sentry. Note that if you choose not to send state to Sentry, your errors might not have the latest version of the state attached. By default, we attach all state changes.

Copied
const sentryReduxEnhancer = Sentry.createReduxEnhancer({
  stateTransformer: state => {
    if (state.topSecret.doNotSend) {
      // Return null to not send this version of the state.
      return null;
    }

    // Transform the state to remove sensitive information
    const transformedState = {
      ...state,
      topSecret: {
        ...state.topSecret,
        // Replace sensitive information with something else
        nuclearLaunchCodes: "I love pizza",
        // or just remove it entirely
        hiddenTreasureLocation: null,
      },
      // You should also remove large data that is irrelevant to debugging to not clutter your Sentry issues
      giganticState: null,
    };

    return transformedState;
  },
});

configureScopeWithState (Function)
Called on every state update, configure the Sentry Scope with the Redux state. The first parameter is the scope, which is the same scope instance that you would get when you call Sentry.configureScope, and the second parameter is the latest Redux state.

Copied
const sentryReduxEnhancer = Sentry.createReduxEnhancer({
  configureScopeWithState: (scope, state) => {
    // Set tag if the user is using imperial units.
    if (state.settings.useImperialUnits) {
      scope.setTag("user.usesImperialUnits", true);
    }
  },
});

Next Steps: