Photo by KT on Unsplash

Redux + Nextjs WTF

Thu Feb 18 2021

Redux and Nextjs are two very powerful tools for a web developer comfortable with React. Redux allows for one central store for all the state needs throughout an entire application. Nextjs is a framework designed for Server-Side Rendering (SSR) — opening the door for better SEO and faster load times. Individually, these tools can supercharge your web app. It then seems logical that used together, your app could rule the world.

The problem is: Redux and Nextjs don’t seem to play very well together.

This is not to say that using them together to get the specific features you want from each library is not possible; it’s just complicated.

For that reason, I’d like to cover one of the more difficult parts of a Redux/Nextjs design that I’ve encountered: dynamic urls.

Nextjs provides a simple-ish way to deal with dynamic urls. For this example, we’ll assume that the urls you are looking for match the pattern, where :slug is the dynamic part of the url. We’ll also assume that you’re using the next-redux-wrapper from kirill-konshin (which seems to be the almost-universally accepted package for dealing with this pair-up), and that you’ve followed the basic setup instructions on both and kirill’s GitHub.

  1. In your pages folder, create a folder called blog.

  2. In your pages/blog folder, create a file called index.js

  3. In pages/blog/index.js create your basic Post component. Mine looks like:

    const Post = props => {
    const { post } = props
    const { title, content, created_at, updated_at } = post

    return (
        <h6>{(created_at === updated_at) ? 'Posted at' : 'Updated at'} {updated_at}</h6>

    export default Post

  4. Within the same file (but outside of your Post component), export an asynchronous function called getStaticPaths

    import { store } from '/path/to/store/setup/according/to/kirills/instructions'

    export const getStaticPaths = async () => {

      let posts = store.getState().posts

      if (posts.length < 1) {
        const postAction = await store.dispatch(fetchAllPosts())
        posts = postAction.payload.posts

      const paths = => ({
        params: {
          slug: post.slug,

      return {
        fallback: true,


    Note that for getStaticPaths to have access to the store, you must import it directly from your store setup file (or create it in this file, which is not recommended due to complexity). This is because getStaticPaths is one of the first functions run from this page (during SSR), and next-redux-wrapper does not provide a wrapper for getStaticPaths. Also, I chose fallback: true because I have a custom display if someone types in a url referencing a post that doesn’t exist (not featured here). You could set it to false if you prefer to throw a 404 instead. fetchAllPosts is a function in postActions that handles all the fetching from the API.

  5. getStaticPaths requires that you also export the asynchronous function getStaticProps

    import { storeWrapper } from '/path/to/store/setup/according/to/kirills/instructions'

    const getStaticProps = storeWrapper.getStaticProps(async ({ store, params }) => {

      let post

      if (store.getState().posts && store.getState().posts.length > 1) {
        post = store.getState().posts.filter(post_ => post_.slug === params.slug)[0]
      } else {
        const response = await fetch(`api.domain/posts/${params.slug}`, {
          method: 'GET',
          mode: 'cors',
          headers: {
            'Content-Type': 'application/json',
        post = await response.json()

      return {
        props: {


    Notice that this function is wrapped with the function you created in kirill’s setup (which I renamed as storeWrapper instead of wrapper for clarity). The store this function receives is that store (which is the same one you imported in the previous function). The params variable comes from getStaticPaths.

That’s pretty much it. You’ll set up your actions and reducers as normal for Redux with one exception: your actions must actually return the dispatched action objects, not just simply dispatch them. As you can see, setting up Redux with Nextjs takes a few extra tweaks, but it’s not too bad. Once you’re finished, the end result is quite amazing: pages rendered server side with a single source of truth for managing state in all your pages.

Happy coding!