Writing

Re-enabling SSR on a Next.js app trapped behind redux-persist

Apr 15, 2026 · 8 min read

There is a kind of bug that is hard to see because nothing breaks. The page renders. The data shows up. Lighthouse gives you an okay-ish score. And yet somewhere along the way, your Next.js app has quietly become a single-page application that bills itself as server-rendered.

This is the story of one of those.

The setup

We had a Next.js app at eBuddy that needed offline-friendly state on the client. Someone (me, eventually) reached for redux-persist. It works, it’s familiar, and it gets the job done. The catch is that redux-persist writes to localStorage, and localStorage does not exist on the server. The standard workaround is to wrap the app in a PersistGate that waits for hydration before rendering anything. Functionally fine. Architecturally, it means the entire tree under that gate renders empty on the server.

We had effectively disabled SSR. None of the marketing pages, none of the listings, none of the SEO-relevant content was reaching crawlers.

The fix

The fix is not to remove redux-persist; it earns its keep on the client. The fix is to keep state hydration off the critical path so the server can still render the parts that matter.

A few things stacked together: splitting the persisted slice from the non-persisted state, pushing the gate down to a sub-tree, and accepting that some state arrives a beat late on the client. The render-blank moment on first paint is gone.

The SEO score lifted by 50%. The JS bundle shrank. Nothing about the user-facing experience felt different, which is the whole point.

The lesson

The lesson, the one I keep relearning: the libraries you reach for first will shape the architecture you end up with. There is no such thing as a neutral dependency. Pick the ones that fit the rendering model you actually want, not the ones that look familiar.