How to use Redux devtools with Nextjs?

Viewed 2984

I'm trying to use the Redux DevTools extension on my Next.js application. The redux is working fine but I'm not being able to see the state in the devtools.

What am I doing wrong and how can I fix it?

_app.js:



function MyApp({ Component, pageProps }) {
  const store = useStore(pageProps.initialReduxState);

  return (
    <Provider store={store}>
      <Component {...pageProps} />
    </Provider>
  )
}

let store;

function initStore(initialState) {
    const composeEnhancers = typeof window !== 'undefined' && window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;

  return createStore(
    reducers,
    initialState,
    composeEnhancers(
        applyMiddleware(thunkMiddleware)
    )
  )
}

function useStore(initialState) {
  const store = useMemo(() => initializeStore(initialState), [initialState])
  return store
}

const initializeStore = (preloadedState) => {
  let _store = store ?? initStore(preloadedState)

  if (preloadedState && store) {
    _store = initStore({
      ...store.getState(),
      ...preloadedState,
    })
    store = undefined
  }

  if (typeof window === 'undefined') return _store
  if (!store) store = _store

  return _store
}
3 Answers

The problem is that devtools only runs in the browser, as nextjs is a framework that execute javascript in node before it comes to the browser.

Solution? add the condition if (typeof window !== 'undefined') to the composeEnhancers section. I did something like this in my code:

// ---Redux DevTools
let composeEnhancers = compose;
if (typeof window !== 'undefined') {
  composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
}

This ensures your redux devtools configuration only runs in the browser :D

I am using next-redux wrapper and this is how I set it:

const bindMiddleware = (middleware) => {
  if (process.env.NODE_ENV !== "production") {
   // I require this only in dev environment
    const { composeWithDevTools } = require("redux-devtools-extension");
    return composeWithDevTools(applyMiddleware(...middleware));
  }
  return applyMiddleware(...middleware);
};

export const makeStore = (context) => {
  const store = createStore(
    rootReducer,
    bindMiddleware([thunk])
  );
  return store;
};

using ternary operator

=>

const store = createStore(   todoReducer,   typeof window !== "undefined"
    ? window.__REDUX_DEVTOOLS_EXTENSION__ &&
        window.__REDUX_DEVTOOLS_EXTENSION__()
    : null ); 
Related