# getDefaultMiddleware

&#x20;

## `getDefaultMiddleware`

Returns an array containing the default list of middleware.

### Intended Usage

By default, [`configureStore`](https://bryan-guner.gitbook.io/my-docs/redux/repos/redux-toolkit/docs/api/configurestore) adds some middleware to the Redux store setup automatically.

```js
const store = configureStore({
  reducer: rootReducer,
})

// Store has middleware added, because the middleware list was not customized
```

If you want to customize the list of middleware, you can supply an array of middleware functions to `configureStore`:

```js
const store = configureStore({
  reducer: rootReducer,
  middleware: [thunk, logger],
})

// Store specifically has the thunk and logger middleware applied
```

However, when you supply the `middleware` option, you are responsible for defining *all* the middleware you want added to the store. `configureStore` will not add any extra middleware beyond what you listed.

`getDefaultMiddleware` is useful if you want to add some custom middleware, but also still want to have the default middleware added as well:

```ts
// file: reducer.ts noEmit

export default function rootReducer(state = {}, action: any) {
  return state
}

// file: store.ts
import { configureStore } from '@reduxjs/toolkit'

import logger from 'redux-logger'

import rootReducer from './reducer'

const store = configureStore({
  reducer: rootReducer,
  middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(logger),
})

// Store has all of the default middleware added, _plus_ the logger middleware
```

It is preferrable to use the chainable `.concat(...)` and `.prepend(...)` methods of the returned `MiddlewareArray` instead of the array spread operator, as the latter can lose valuable type information under some circumstances.

### getDefaultMiddleware import

While the callback notation with `configureStore` shown in the last example is the recommended way of using `getDefaultMiddleware`, it can also be imported to be used independently from 'configureStore':

```ts
// file: reducer.ts noEmit

export default function rootReducer(state = {}, action: any) {
  return state
}

// file: store.ts
import { getDefaultMiddleware } from '@reduxjs/toolkit'

interface State {
  // ...
}

const middlewares = getDefaultMiddleware<State>()
```

The benefit of using the callback notation is that the `State` type is already pre-bound, which might prevent circular type references when trying to specify generics by hand.

### Included Default Middleware

#### Development

One of the goals of Redux Toolkit is to provide opinionated defaults and prevent common mistakes. As part of that, `getDefaultMiddleware` includes some middleware that are added **in development builds of your app only** to provide runtime checks for two common issues:

* [Immutability check middleware](https://bryan-guner.gitbook.io/my-docs/redux/repos/redux-toolkit/docs/api/immutabilitymiddleware): deeply compares state values for mutations. It can detect mutations in reducers during a dispatch, and also mutations that occur between dispatches (such as in a component or a selector). When a mutation is detected, it will throw an error and indicate the key path for where the mutated value was detected in the state tree. (Forked from [`redux-immutable-state-invariant`](https://github.com/leoasis/redux-immutable-state-invariant).)
* [Serializability check middleware](https://bryan-guner.gitbook.io/my-docs/redux/repos/redux-toolkit/docs/api/serializabilitymiddleware): a custom middleware created specifically for use in Redux Toolkit. Similar in concept to `immutable-state-invariant`, but deeply checks your state tree and your actions for non-serializable values such as functions, Promises, Symbols, and other non-plain-JS-data values. When a non-serializable value is detected, a console error will be printed with the key path for where the non-serializable value was detected.

In addition to these development tool middleware, it also adds [`redux-thunk`](https://github.com/reduxjs/redux-thunk) by default, since thunks are the basic recommended side effects middleware for Redux.

Currently, the return value is:

```js
const middleware = [thunk, immutableStateInvariant, serializableStateInvariant]
```

#### Production

Currently, the return value is:

```js
const middleware = [thunk]
```

### Customizing the Included Middleware

`getDefaultMiddleware` accepts an options object that allows customizing each middleware in two ways:

* Each middleware can be excluded the result array by passing `false` for its corresponding field
* Each middleware can have its options customized by passing the matching options object for its corresponding field

This example shows excluding the serializable state check middleware, and passing a specific value for the thunk middleware's "extra argument":

```ts
// file: reducer.ts noEmit

export default function rootReducer(state = {}, action: any) {
  return state
}

// file: api.ts noEmit

export declare const myCustomApiService: any

// file: store.ts

import { configureStore } from '@reduxjs/toolkit'
import rootReducer from './reducer'
import { myCustomApiService } from './api'

const store = configureStore({
  reducer: rootReducer,
  middleware: (getDefaultMiddleware) =>
    getDefaultMiddleware({
      thunk: {
        extraArgument: myCustomApiService,
      },
      serializableCheck: false,
    }),
})
```

### API Reference

```ts
interface ThunkOptions<E = any> {
  extraArgument: E
}

interface ImmutableStateInvariantMiddlewareOptions {
  // See "Immutability Middleware" page for definition
}

interface SerializableStateInvariantMiddlewareOptions {
  // See "Serializability Middleware" page for definition
}

interface GetDefaultMiddlewareOptions {
  thunk?: boolean | ThunkOptions
  immutableCheck?: boolean | ImmutableStateInvariantMiddlewareOptions
  serializableCheck?: boolean | SerializableStateInvariantMiddlewareOptions
}

function getDefaultMiddleware<S = any>(
  options: GetDefaultMiddlewareOptions = {}
): Middleware<{}, S>[]
```
