{"id":17900,"library":"redux-cablecar","title":"Redux CableCar","description":"redux-cablecar is Redux middleware designed to seamlessly integrate Redux actions with Rails Action Cable. It establishes a WebSocket connection, enabling automatic transmission of specified client-side Redux actions to a Rails server and converting server messages back into client-side Redux actions. The current stable version is 5.0.7. The package appears to follow a maintenance-oriented release cadence, primarily focusing on dependency updates and Node.js compatibility, as evidenced by recent changes in the v5.x series. Its key differentiator is providing a direct, opinionated bridge between the Redux state management pattern in a frontend application and the real-time capabilities of a Rails backend via Action Cable, simplifying the setup for bi-directional communication over WebSockets. This allows developers to treat server interactions as standard Redux actions, abstracting away much of the underlying WebSocket management.","status":"maintenance","version":"5.0.7","language":"javascript","source_language":"en","source_url":"https://github.com/ndhays/redux-cablecar","tags":["javascript","cablecar","actioncable","rails","rails5","redux","redux-cablecar"],"install":[{"cmd":"npm install redux-cablecar","lang":"bash","label":"npm"},{"cmd":"yarn add redux-cablecar","lang":"bash","label":"yarn"},{"cmd":"pnpm add redux-cablecar","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Required as a Redux store is passed to connect and it's middleware; it is a peer dependency.","package":"redux","optional":false},{"reason":"Often used alongside Redux for modern Redux development and listed as a peer dependency. Provides `configureStore` and simplifies `applyMiddleware` setup.","package":"@reduxjs/toolkit","optional":true}],"imports":[{"note":"This is the primary factory function for creating the CableCar route and middleware. Modern applications typically use ESM `import`.","wrong":"const { createCableCarRoute } = require('redux-cablecar')","symbol":"createCableCarRoute","correct":"import { createCableCarRoute } from 'redux-cablecar'"},{"note":"The middleware function itself is obtained by calling `createMiddleware()` on the `cableCarRoute` instance, not as a direct export.","wrong":"import { createCableCarMiddleware } from 'redux-cablecar'","symbol":"createMiddleware (via route instance)","correct":"const cableCarRoute = createCableCarRoute(); const cableCarMiddleware = cableCarRoute.createMiddleware();"},{"note":"The `connect` method is invoked on the `cableCarRoute` instance to establish the WebSocket connection with ActionCable, rather than being a standalone import.","wrong":"import { connect } from 'redux-cablecar'","symbol":"connect (via route instance)","correct":"cableCarRoute.connect(store, 'MainChannel', options)"}],"quickstart":{"code":"import { configureStore } from '@reduxjs/toolkit';\nimport { createCableCarRoute } from 'redux-cablecar';\n\n// A dummy reducer for demonstration purposes\nconst initialState = { messages: [] };\nfunction reducer(state = initialState, action) {\n  switch (action.type) {\n    case 'MESSAGE_RECEIVED_FROM_RAILS':\n      return { ...state, messages: [...state.messages, action.payload] };\n    case 'RAILS_SEND_MESSAGE':\n      // This action will be intercepted by CableCar and sent to Rails\n      console.log('Dispatching RAILS_SEND_MESSAGE, CableCar will forward this:', action.payload);\n      return state;\n    default:\n      return state;\n  }\n}\n\n// Step 1: Create cablecar route and middleware\nconst cableCarRoute = createCableCarRoute();\nconst cableCarMiddleware = cableCarRoute.createMiddleware();\n\n// Step 2: Add middleware to the Redux store\n// Using configureStore from Redux Toolkit for modern setup\nconst store = configureStore({\n  reducer: reducer,\n  middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(cableCarMiddleware),\n  devTools: process.env.NODE_ENV !== 'production' // Enable Redux DevTools\n});\n\n// Step 3: Initialize the cablecar connection to the Redux store and a Rails ActionCable channel\nconst options = {\n    // Parameters sent to the Rails channel when subscribing (e.g., params[:room])\n    params: { room: 'chat_room_1' },\n    // Define which Redux actions should be sent to the Rails server.\n    // By default, it matches actions with type prefix 'RAILS_'.\n    permittedActions: ['RAILS_SEND_MESSAGE', /^CLIENT_TO_SERVER_/],\n    // ActionCable Callbacks\n    initialized: () => console.log('CableCar initialized.'),\n    connected: () => console.log('CableCar connected to MainChannel!'),\n    disconnected: () => console.log('CableCar disconnected.'),\n    rejected: () => console.error('CableCar connection rejected.')\n};\n\nconst cableCar = cableCarRoute.connect(store, 'MainChannel', options);\n\n// Example of dispatching an action that will be sent to the server\nstore.dispatch({ type: 'RAILS_SEND_MESSAGE', payload: { text: 'Hello from Redux!', author: 'Client' } });\n\n// Example of an action that will NOT be sent to the server (unless explicitly permitted)\nstore.dispatch({ type: 'LOCAL_ACTION', payload: 'This stays client-side.' });\n\nconsole.log('Redux store and CableCar middleware initialized. Check console for dispatches.');\n","lang":"javascript","description":"This quickstart demonstrates the full setup of `redux-cablecar` by creating a Redux store using Redux Toolkit, applying the CableCar middleware, connecting to a simulated Rails ActionCable 'MainChannel' with custom parameters and action filtering, and dispatching an action intended for the server. It also shows an example of a local action not sent to the server."},"warnings":[{"fix":"Review the v5 API documentation and update your initialization code to use `createCableCarRoute()` and `cableCarRoute.connect(store, channel, options)`.","message":"Version 5.0.0 introduced significant breaking changes, migrating from `createActionCable` and `createChannel` APIs to the new `createCableCarRoute` and `#connect` pattern. Direct migration from v4 to v5 requires rewriting how the CableCar middleware and connection are initialized.","severity":"breaking","affected_versions":">=5.0.0"},{"fix":"Configure the `permittedActions` option in `cableCarRoute.connect()` to correctly match the Redux action types you intend to send to the server. This can be a string prefix, a regular expression, an array of both, or a custom function.","message":"Actions are only sent to the Rails server if their type matches the `permittedActions` configuration. The default `permittedActions` is any action with a type prefix `RAILS_` (e.g., `{ type: 'RAILS_ACTION' }`). If your actions don't match this or a custom pattern, they will not be forwarded to ActionCable.","severity":"gotcha","affected_versions":">=3.0.0"},{"fix":"Pass `cableCarMiddleware` to `configureStore`'s `middleware` option, typically by concatenating it with `getDefaultMiddleware()`, e.g., `middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(cableCarMiddleware)`.","message":"When using `redux-cablecar` with Redux Toolkit's `configureStore`, ensure you correctly integrate the CableCar middleware into the `middleware` array. Incorrect placement or setup can prevent actions from being processed or interfere with other Redux Toolkit middleware.","severity":"gotcha","affected_versions":">=5.0.0"}],"env_vars":null,"last_verified":"2026-04-23T00:00:00.000Z","next_check":"2026-07-22T00:00:00.000Z","problems":[{"fix":"Ensure `createCableCarRoute` is called as a function to get the route instance: `const cableCarRoute = createCableCarRoute();` then call `cableCarRoute.createMiddleware()`.","cause":"Attempting to call `createMiddleware()` directly on the imported `createCableCarRoute` without first invoking `createCableCarRoute` as a function to get an instance.","error":"TypeError: Cannot read properties of undefined (reading 'createMiddleware')"},{"fix":"Verify that the `type` property of the dispatched Redux action adheres to the `permittedActions` specified in `cableCarRoute.connect()`. Remember the default is a `RAILS_` prefix if `permittedActions` is not explicitly set.","cause":"The Redux action type dispatched from the client does not match any of the patterns defined in the `permittedActions` configuration for the CableCar connection.","error":"Action did not reach Rails server as expected."},{"fix":"Check the `webSocketURL` option in `createCableCarRoute()` if a custom URL is used (otherwise, it defaults to the host). Ensure the `channel` name passed to `cableCarRoute.connect()` exactly matches your Rails ActionCable channel name (e.g., 'MainChannel'). Verify your Rails channel `subscribed` method is correctly implemented and the server is running.","cause":"The ActionCable server URL is incorrect or unreachable, the channel name is misspelled, or the Rails server-side channel is not properly defined or subscribed.","error":"WebSocket connection failed during CableCar initialization."}],"ecosystem":"npm","meta_description":null,"install_score":null,"install_tag":null,"quickstart_score":null,"quickstart_tag":null}