I'm trying to migrate an existing React/Vite app (currently using React Router v7, along with redux, rtk-query, and redux-persist) to use React Router v7 in Framework mode. I'm hitting an error when I try to run the app using npm run dev
:
redux-persist failed to create sync storage. falling back to noop storage.
[vite] (ssr) Error when evaluating SSR module virtual:react-router/server-build: storage.getItem is not a function
...
[vite] Internal server error: storage.getItem is not a function
I can recreate the problem on a fresh app: npx create-react-router@latest
./react-router.config.ts
import type { Config } from "@react-router/dev/config";
export default {
ssr: false,
} satisfies Config;
./app/store/store.js
import { configureStore } from "@reduxjs/toolkit";
import storage from "redux-persist/lib/storage";
import { persistReducer, persistStore } from "redux-persist";
import auth from "./authSlice";
const persistConfig = {
key: "root",
storage,
};
export const reducer = persistReducer(persistConfig, auth);
export const store = configureStore({ reducer });
export const persistor = persistStore(store);
./app/store/authSlice.js
import { createSlice } from "@reduxjs/toolkit";
export const authSlice = createSlice({
name: "auth",
initialState: { token: "" },
reducers: {
setToken(state, action) {
state.token = action.payload;
},
},
});
export default authSlice.reducer;
And editing root.tsx
to add a <Provider />
:
import { Provider } from "react-redux";
import { store } from "./store/store";
...
export default function App() {
return (
<Provider store={store}>
<Outlet />
</Provider>
);
}
./package.json
{
...
"scripts": {
...
"dev": "react-router dev",
},
"dependencies": {
"@react-router/node": "^7.7.1",
"@react-router/serve": "^7.7.1",
"@reduxjs/toolkit": "^2.8.2",
"isbot": "^5.1.27",
"react": "^19.1.0",
"react-dom": "^19.1.0",
"react-redux": "^9.2.0",
"react-router": "^7.7.1",
"redux": "^5.0.1",
"redux-persist": "^6.0.0"
},
"devDependencies": {
"@react-router/dev": "^7.7.1",
"@tailwindcss/vite": "^4.1.4",
"@types/node": "^20",
"@types/react": "^19.1.2",
"@types/react-dom": "^19.1.2",
"tailwindcss": "^4.1.4",
"typescript": "^5.8.3",
"vite": "^6.3.3",
"vite-tsconfig-paths": "^5.1.4"
}
}
Any ideas how I can get Framework mode up and running without completely replacing redux-persist?
The issue seemed to be with the storage
imported from redux-persist
- the "noop storage" it falls back to lacks required methods. Following this solution (from a similar Next.js issue) seemed to address the problem. I made these changes to ./app/store/store.js
:
// import storage from "redux-persist/lib/storage";
import createWebStorage from "redux-persist/lib/storage/createWebStorage";
const createNoopStorage = () => {
return {
getItem(_key) {
return Promise.resolve(null);
},
setItem(_key, value) {
return Promise.resolve(value);
},
removeItem(_key) {
return Promise.resolve();
},
};
};
const storage =
typeof window === "undefined"
? createNoopStorage()
: createWebStorage("local");
This seems to have solved the issue.