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

# Redux Middleware

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 };
```
