> ## Documentation Index
> Fetch the complete documentation index at: https://velt-mintlify-e6426361.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Live State Sync Redux Middleware

> Sync Redux store state across all connected clients in real time using Velt's createLiveStateMiddleware for React and Next.js collaborative apps.

If you are using Redux, you can use our middleware to sync state changes directly into your Redux store.

## Step 1: Import the middleware

To get started import the `createLiveStateMiddleware` middleware from the Velt SDK.

```jsx theme={null}
import { createLiveStateMiddleware } from "@veltdev/react";
```

## Step 2: Add the middleware to your Redux store configuration

Use `createLiveStateMiddleware` to create a `middleware` and a `updateLiveStateDataId` method.

Then add the created `middleware` to your Redux store configuration.

You can also export the `updateLiveStateDataId` method from your Redux store. This method will be used to dynamically set the `liveStateDataId`.

**store.js**:

```jsx theme={null}
import { configureStore } from "@reduxjs/toolkit";
import { createLiveStateMiddleware } from "@veltdev/react";

//create middleware
const { middleware, updateLiveStateDataId } = createLiveStateMiddleware();

//add middleware to your Redux store configuration
export const store = configureStore({
  reducer: {
	... your reducers here
  },
  // You just have to concat our liveStateMiddleware in store
  middleware: getDefaultMiddleware => getDefaultMiddleware().concat(middleware)
});

// optionally export updateLiveStateDataId method if you want to set liveStateDataId dynamically
export { updateLiveStateDataId };
```

## Step 3: Selectively sync actions

`createLiveStateMiddleware` takes in an optional configuration object with the following schema:

```tsx theme={null}
type LiveStateMiddlewareConfig = {
    allowedActionTypes?: Set<string>,
    disabledActionTypes?: Set<string>,
    allowAction?: (action: any) => boolean,
    liveStateDataId?: string,
};
```

You can use it to define the following fields:

* `allowedActionTypes` - allow live state syncing on specific action types only
* `disabledActionTypes` - restrict live state syncing on specific action types
* `allowAction` - custom callback method to dynamically decide to allow or disable syncing for that action. Return `true` to allow the action and `false` to restrict the action.
* `liveStateDataId` - used to set a custom string value as live state data key. If not provided, we will store data in default key.

Example:

```jsx theme={null}
const { middleware, updateLiveStateDataId } = createLiveStateMiddleware({
	allowedActionTypes: new Set(['action1', 'action2']),
	disabledActionTypes: new Set(['disabledAction1', 'disabledAction2']),
	allowAction: (action) => {
		// return true to allow this action, false to restrict this action from syncing
    },
    liveStateDataId: 'custom-live-state-data-id'
});
```

<Info>
  It is recommended to first set a custom `liveStateDataId` in the middleware configuration. You can then change it dynamically later using the `updateLiveStateDataId` method.
</Info>

To set `liveStateDataId` dynamically, call the `updateLiveStateDataId` method that was previously created and exported from your store.

```jsx theme={null}
import { updateLiveStateDataId } from 'path-to-store.js';

function YourComponent() {
	
	// You can update liveStateDataId any time based on your requirements and all the actions called after that will be synced on new ID path.
	const setLiveStateDataId = (id) => {
		updateLiveStateDataId(id);
    }

	return (
        <div>Your HTML Template</div>
    );
}
```

## Step 4: Action Data Structure

The middleware automatically adds a UTC timestamp to each synced Redux action. The action data structure includes:

```json theme={null}
{
    "id": "ACTION_ID",
    "action": {
        "type": "ACTION_TYPE",
        "payload": "ACTION_PAYLOAD" // optional
    },
    "timestamp": 1759745729823 // UTC timestamp in milliseconds (automatically added)
}
```

The `timestamp` field is automatically added by the middleware and represents the UTC time in milliseconds when the action was dispatched. This helps with action ordering and debugging across distributed clients.

## Complete Example

Here's a complete example showing how to set up the Redux middleware with all configuration options:

```jsx theme={null}
// store.js
import { configureStore } from "@reduxjs/toolkit";
import { createLiveStateMiddleware } from "@veltdev/react";

//create middleware and updateLiveStateDataId method
const { middleware, updateLiveStateDataId } = createLiveStateMiddleware({
	allowedActionTypes: new Set(['action1', 'action2']),
	disabledActionTypes: new Set(['disabledAction1', 'disabledAction2']),
	allowAction: (action) => {
		// return true to allow this action, false to restrict this action from syncing
    },
    liveStateDataId: 'custom-live-state-data-id'
});

//add middleware to your Redux store configuration
export const store = configureStore({
  reducer: {
	... your reducers here
  },
  // You just have to concat our liveStateMiddleware in store
  middleware: getDefaultMiddleware => getDefaultMiddleware().concat(middleware)
});

// you can optionally export the updateLiveStateDataId method if you want to set liveStateDataId dynamically
export { updateLiveStateDataId };
```
