{"id":221137,"date":"2021-04-07T16:00:26","date_gmt":"2021-04-07T13:00:26","guid":{"rendered":"https:\/\/en.buradabiliyorum.com\/how-to-sync-a-redux-store-across-browser-tabs-cloudsavvy-it\/"},"modified":"2021-04-07T16:00:26","modified_gmt":"2021-04-07T13:00:26","slug":"how-to-sync-a-redux-store-across-browser-tabs-cloudsavvy-it","status":"publish","type":"post","link":"https:\/\/buradabiliyorum.com\/en\/how-to-sync-a-redux-store-across-browser-tabs-cloudsavvy-it\/","title":{"rendered":"#How to Sync a Redux Store Across Browser Tabs \u2013 CloudSavvy IT"},"content":{"rendered":"<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_84 counter-hierarchy ez-toc-counter ez-toc-custom ez-toc-container-direction\">\n<p class=\"ez-toc-title\" style=\"cursor:inherit\">Table of Contents<\/p>\n<label for=\"ez-toc-cssicon-toggle-item-6a25ead9b040f\" class=\"ez-toc-cssicon-toggle-label\"><span class=\"\"><span class=\"eztoc-hide\" style=\"display:none;\">Toggle<\/span><span class=\"ez-toc-icon-toggle-span\"><svg style=\"fill: #dd3333;color:#dd3333\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" class=\"list-377408\" width=\"20px\" height=\"20px\" viewBox=\"0 0 24 24\" fill=\"none\"><path d=\"M6 6H4v2h2V6zm14 0H8v2h12V6zM4 11h2v2H4v-2zm16 0H8v2h12v-2zM4 16h2v2H4v-2zm16 0H8v2h12v-2z\" fill=\"currentColor\"><\/path><\/svg><svg style=\"fill: #dd3333;color:#dd3333\" class=\"arrow-unsorted-368013\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"10px\" height=\"10px\" viewBox=\"0 0 24 24\" version=\"1.2\" baseProfile=\"tiny\"><path d=\"M18.2 9.3l-6.2-6.3-6.2 6.3c-.2.2-.3.4-.3.7s.1.5.3.7c.2.2.4.3.7.3h11c.3 0 .5-.1.7-.3.2-.2.3-.5.3-.7s-.1-.5-.3-.7zM5.8 14.7l6.2 6.3 6.2-6.3c.2-.2.3-.5.3-.7s-.1-.5-.3-.7c-.2-.2-.4-.3-.7-.3h-11c-.3 0-.5.1-.7.3-.2.2-.3.5-.3.7s.1.5.3.7z\"\/><\/svg><\/span><\/span><\/label><input type=\"checkbox\"  id=\"ez-toc-cssicon-toggle-item-6a25ead9b040f\" checked aria-label=\"Toggle\" \/><nav><ul class='ez-toc-list ez-toc-list-level-1 ' ><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/buradabiliyorum.com\/en\/how-to-sync-a-redux-store-across-browser-tabs-cloudsavvy-it\/#Overview\" >Overview<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/buradabiliyorum.com\/en\/how-to-sync-a-redux-store-across-browser-tabs-cloudsavvy-it\/#Synchronising_Your_Store\" >Synchronising Your Store<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-3\" href=\"https:\/\/buradabiliyorum.com\/en\/how-to-sync-a-redux-store-across-browser-tabs-cloudsavvy-it\/#Customised_Synchronisation\" >Customised Synchronisation<\/a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-4\" href=\"https:\/\/buradabiliyorum.com\/en\/how-to-sync-a-redux-store-across-browser-tabs-cloudsavvy-it\/#Excluding_Actions\" >Excluding Actions<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-5\" href=\"https:\/\/buradabiliyorum.com\/en\/how-to-sync-a-redux-store-across-browser-tabs-cloudsavvy-it\/#Precisely_Filtering_Actions\" >Precisely Filtering Actions<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-6\" href=\"https:\/\/buradabiliyorum.com\/en\/how-to-sync-a-redux-store-across-browser-tabs-cloudsavvy-it\/#Broadcast_Channel_Settings\" >Broadcast Channel Settings<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-7\" href=\"https:\/\/buradabiliyorum.com\/en\/how-to-sync-a-redux-store-across-browser-tabs-cloudsavvy-it\/#Integrating_With_Redux-Persist\" >Integrating With Redux-Persist<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-8\" href=\"https:\/\/buradabiliyorum.com\/en\/how-to-sync-a-redux-store-across-browser-tabs-cloudsavvy-it\/#Summary\" >Summary<\/a><\/li><\/ul><\/nav><\/div>\n<p><strong>&#8220;#How to Sync a Redux Store Across Browser Tabs \u2013 CloudSavvy IT&#8221;<\/strong><\/p>\n<div id=\"article-content-area\">\n<img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-9781\" data-pagespeed-lazy-src=\"https:\/\/www.cloudsavvyit.com\/p\/uploads\/2021\/02\/99128fa6.jpg?width=1200&amp;trim=1,1&amp;bg-color=000&amp;pad=1,1\" alt=\"Illustration showing the Redux logo\" width=\"1602\" height=\"902\" src=\"\/pagespeed_static\/1.JiBnMqyl6S.gif\" onload=\"pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);\" onerror=\"this.onerror=null;pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);\"\/><\/p>\n<p>Redux is a convenient way to manage state in complex web <a href=\"https:\/\/buradabiliyorum.com\/en\/category\/download-scripts-themes-apps\/\" data-internallinksmanager029f6b8e52c=\"9\" title=\"Download Scripts &amp; Themes &amp; Apps\" target=\"_blank\" rel=\"noopener\">app<\/a>s. Your Redux store isn\u2019t synced across tabs though, which can lead to some awkward scenarios. If the user logs out in one tab, it would be ideal for that action to be reflected in their other open tabs.<\/p>\n<p>You can add cross-tab store synchronisation using the <a rel=\"nofollow noopener\" target=\"_blank\" href=\"https:\/\/www.npmjs.com\/package\/redux-state-sync\">react-state-sync<\/a> library. This provides a middleware which automatically syncs the store across tabs. You don\u2019t need to manually intervene in the sync process after the initial setup.<\/p>\n<h2 id=\"overview\"><span class=\"ez-toc-section\" id=\"Overview\"><\/span>Overview<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>The Redux State Sync library offers a Redux middleware which you need to add to your store. When the store receives an action, the middleware will dispatch the same action in any other tabs open to your site.<\/p>\n<p>Each tab sets up its own message listener to receive incoming action notifications. When the listener is notified, it will dispatch the action into the tab\u2019s store.<\/p>\n<p>Messages are exchanged between tabs using the <a rel=\"nofollow noopener\" target=\"_blank\" href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/Broadcast_Channel_API\">Broadcast Channel API<\/a>. This is a browser feature which allows tabs from the same origin to communicate with each other. Tabs \u201csubscribe\u201d to \u201cchannels.\u201d They\u2019re notified by the browser when another tab posts a message to a subscribed channel.<\/p>\n<p>Broadcast Channel is only available in newer browsers. Redux State Sync uses an abstraction which can fallback to alternative technologies. When Broadcast Channel is unsupported, IndexedDB or LocalStorage will be used instead.<\/p>\n<p>The use of Broadcast Channel places some limitations on what you can send between tabs. Data you dispatch must be supported by the browser\u2019s <a rel=\"nofollow noopener\" target=\"_blank\" href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/Web_Workers_API\/Structured_clone_algorithm\">structured clone algorithm<\/a>. This includes scalar values, arrays, plain JavaScript objects and blobs. Complex values will not be transferred exactly.<\/p>\n<h2 id=\"synchronising-your-store\"><span class=\"ez-toc-section\" id=\"Synchronising_Your_Store\"><\/span>Synchronising Your Store<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>To start using Redux State Sync, add it to your project via npm:<\/p>\n<pre>npm install redux-state-sync<\/pre>\n<p>Next, create a basic store. We\u2019ll modify this code in a moment to add Redux State Sync.<\/p>\n<div class=\"wp-geshi-highlight-wrap5\">\n<div class=\"wp-geshi-highlight-wrap4\">\n<div class=\"wp-geshi-highlight-wrap3\">\n<div class=\"wp-geshi-highlight-wrap2\">\n<div class=\"wp-geshi-highlight-wrap\">\n<div class=\"wp-geshi-highlight\">\n<div class=\"javascript\">\n<pre class=\"de1\"><span class=\"kw5\">import<\/span> <span class=\"br0\">{<\/span>createStore<span class=\"br0\">}<\/span> from <span class=\"st0\">\"redux\"<\/span><span class=\"sy0\">;<\/span>\n\u00a0\n<span class=\"kw1\">const<\/span> state <span class=\"sy0\">=<\/span> <span class=\"br0\">{<\/span>authenticated<span class=\"sy0\">:<\/span> <span class=\"kw2\">false<\/span><span class=\"br0\">}<\/span><span class=\"sy0\">;<\/span>\n\u00a0\n<span class=\"kw1\">const<\/span> reducer <span class=\"sy0\">=<\/span> <span class=\"br0\">(<\/span>state<span class=\"sy0\">,<\/span> action<span class=\"br0\">)<\/span> <span class=\"sy0\">=&gt;<\/span> <span class=\"br0\">(<\/span><span class=\"br0\">{<\/span>...<span class=\"me1\">state<\/span><span class=\"sy0\">,<\/span> ...<span class=\"me1\">action<\/span><span class=\"br0\">}<\/span><span class=\"br0\">)<\/span><span class=\"sy0\">;<\/span>\n\u00a0\n<span class=\"kw1\">const<\/span> store <span class=\"sy0\">=<\/span> createStore<span class=\"br0\">(<\/span>reducer<span class=\"sy0\">,<\/span> state<span class=\"br0\">)<\/span><span class=\"sy0\">;<\/span><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<p>Now we have a simple store. To sync it across tabs, add the Redux State Sync middleware and setup a message listener.<\/p>\n<div class=\"wp-geshi-highlight-wrap5\">\n<div class=\"wp-geshi-highlight-wrap4\">\n<div class=\"wp-geshi-highlight-wrap3\">\n<div class=\"wp-geshi-highlight-wrap2\">\n<div class=\"wp-geshi-highlight-wrap\">\n<div class=\"wp-geshi-highlight\">\n<div class=\"javascript\">\n<pre class=\"de1\"><span class=\"kw5\">import<\/span> <span class=\"br0\">{<\/span>createStore<span class=\"sy0\">,<\/span> applyMiddleware<span class=\"br0\">}<\/span> from <span class=\"st0\">\"redux\"<\/span><span class=\"sy0\">;<\/span>\n<span class=\"kw5\">import<\/span> <span class=\"br0\">{<\/span>createStateSyncMiddleware<span class=\"sy0\">,<\/span> initMessageListener<span class=\"br0\">}<\/span> from <span class=\"st0\">\"redux-state-sync\"<\/span><span class=\"sy0\">;<\/span>\n\u00a0\n<span class=\"kw1\">const<\/span> reduxStateSyncConfig <span class=\"sy0\">=<\/span> <span class=\"br0\">{<\/span><span class=\"br0\">}<\/span><span class=\"sy0\">;<\/span>\n\u00a0\n<span class=\"kw1\">const<\/span> reducer <span class=\"sy0\">=<\/span> <span class=\"br0\">(<\/span>state<span class=\"sy0\">,<\/span> action<span class=\"br0\">)<\/span> <span class=\"sy0\">=&gt;<\/span> <span class=\"br0\">(<\/span><span class=\"br0\">{<\/span>...<span class=\"me1\">state<\/span><span class=\"sy0\">,<\/span> ...<span class=\"me1\">action<\/span><span class=\"br0\">}<\/span><span class=\"br0\">)<\/span><span class=\"sy0\">;<\/span>\n\u00a0\n<span class=\"kw1\">const<\/span> store <span class=\"sy0\">=<\/span> createStore<span class=\"br0\">(<\/span>\n    reducer<span class=\"sy0\">,<\/span>\n    state<span class=\"sy0\">,<\/span>\n    applyMiddleware<span class=\"br0\">(<\/span>createStateSyncMiddleware<span class=\"br0\">(<\/span>reduxStateSyncConfig<span class=\"br0\">)<\/span><span class=\"br0\">)<\/span>\n<span class=\"br0\">)<\/span><span class=\"sy0\">;<\/span>\n\u00a0\ninitMessageListener<span class=\"br0\">(<\/span>store<span class=\"br0\">)<\/span><span class=\"sy0\">;<\/span><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<p>The store is now ready to use across tabs. Open your site in two tabs. Dispatch an action in one of the tabs. You should see the action appear in both stores, effecting the corresponding state change in each. The <a rel=\"nofollow noopener\" target=\"_blank\" href=\"https:\/\/chrome.google.com\/webstore\/detail\/redux-devtools\/lmhkpmbekcpmknklioeibfkpmmfibljd\">Redux DevTools<\/a> extension can be used to monitor incoming actions and the state changes they cause.<\/p>\n<p>The state sync middleware is created using the <code>createStateSyncMiddleware()<\/code> utility function. This accepts a config object used to customise Redux State Sync\u2019s operation. We\u2019ll look more closely at this in the next section.<\/p>\n<p>After the store is created, it\u2019s passed to <code>initMessageListener()<\/code>. This function ensures the cross-tab listening is configured. Without this call, tabs may not receive new actions if no action was dispatched on first load.<\/p>\n<p>Using <code>initMessageListener()<\/code> won\u2019t give your tab access to the existing store held in another tab. When the user opens a new tab, it\u2019ll default to having its own fresh store. If you want new tabs to get their state from an open tab, use the <code>initStateWithPrevTab()<\/code> function instead.<\/p>\n<div class=\"wp-geshi-highlight-wrap5\">\n<div class=\"wp-geshi-highlight-wrap4\">\n<div class=\"wp-geshi-highlight-wrap3\">\n<div class=\"wp-geshi-highlight-wrap2\">\n<div class=\"wp-geshi-highlight-wrap\">\n<div class=\"wp-geshi-highlight\">\n<div class=\"javascript\">\n<pre class=\"de1\"><span class=\"kw1\">const<\/span> store <span class=\"sy0\">=<\/span> createStore<span class=\"br0\">(<\/span>reducer<span class=\"sy0\">,<\/span> state<span class=\"sy0\">,<\/span> applyMiddleware<span class=\"br0\">(<\/span>createStateSyncMiddleware<span class=\"br0\">(<\/span><span class=\"br0\">{<\/span><span class=\"br0\">}<\/span><span class=\"br0\">)<\/span><span class=\"br0\">)<\/span><span class=\"br0\">)<\/span><span class=\"sy0\">;<\/span>\ninitStateWithPrevTab<span class=\"br0\">(<\/span>store<span class=\"br0\">)<\/span><span class=\"sy0\">;<\/span><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<p>The store\u2019s state will be replaced with the existing state if there\u2019s another open tab available.<\/p>\n<h2 id=\"customised-synchronisation\"><span class=\"ez-toc-section\" id=\"Customised_Synchronisation\"><\/span>Customised Synchronisation<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Redux State Sync supports several configuration options to let you customise the synchronisation. Here\u2019s some of the most useful settings. Each one is set as a property in the config object passed to <code>createStateSyncMiddleware()<\/code>.<\/p>\n<h3 id=\"excluding-actions\"><span class=\"ez-toc-section\" id=\"Excluding_Actions\"><\/span>Excluding Actions<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Sometimes you\u2019ll have actions which you don\u2019t want to synchronise. An example could be an action which causes a modal dialog to appear. Chances are you don\u2019t want this dialog to show up in <em>all<\/em> the user\u2019s open tabs!<\/p>\n<p>You can exclude specific named actions using the <code>blacklist<\/code> option. Pass an array of action names as the value.<\/p>\n<div class=\"wp-geshi-highlight-wrap5\">\n<div class=\"wp-geshi-highlight-wrap4\">\n<div class=\"wp-geshi-highlight-wrap3\">\n<div class=\"wp-geshi-highlight-wrap2\">\n<div class=\"wp-geshi-highlight-wrap\">\n<div class=\"wp-geshi-highlight\">\n<div class=\"javascript\">\n<pre class=\"de1\"><span class=\"kw1\">const<\/span> config <span class=\"sy0\">=<\/span> <span class=\"br0\">{<\/span>\n    blacklist<span class=\"sy0\">:<\/span> <span class=\"br0\">[<\/span><span class=\"st0\">\"DEMO_ACTION\"<\/span><span class=\"br0\">]<\/span>\n<span class=\"br0\">}<\/span><span class=\"sy0\">;<\/span>\n\u00a0\n<span class=\"co1\">\/\/ ...<\/span>\n\u00a0\n<span class=\"co1\">\/\/ This won't be synced to any other tabs<\/span>\nStore.<span class=\"me1\">dispatch<\/span><span class=\"br0\">(<\/span><span class=\"br0\">{<\/span>type<span class=\"sy0\">:<\/span> <span class=\"st0\">\"DEMO_ACTION\"<\/span><span class=\"br0\">}<\/span><span class=\"br0\">)<\/span><span class=\"sy0\">;<\/span><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<p>You can also use a whitelist instead of a blacklist. Set the <code>whitelist<\/code> config option to allow only predefined actions to be synchronised.<\/p>\n<h3 id=\"precisely-filtering-actions\"><span class=\"ez-toc-section\" id=\"Precisely_Filtering_Actions\"><\/span>Precisely Filtering Actions<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>If neither <code>blacklist<\/code> or <code>whitelist<\/code> give you enough control, set the <code>predicate<\/code> option. This accepts a function which is used to filter synchronisable actions.<\/p>\n<div class=\"wp-geshi-highlight-wrap5\">\n<div class=\"wp-geshi-highlight-wrap4\">\n<div class=\"wp-geshi-highlight-wrap3\">\n<div class=\"wp-geshi-highlight-wrap2\">\n<div class=\"wp-geshi-highlight-wrap\">\n<div class=\"wp-geshi-highlight\">\n<div class=\"javascript\">\n<pre class=\"de1\"><span class=\"kw1\">const<\/span> config <span class=\"sy0\">=<\/span> <span class=\"br0\">{<\/span>\n    predicate<span class=\"sy0\">:<\/span> action <span class=\"sy0\">=&gt;<\/span> <span class=\"br0\">(<\/span>action.<span class=\"me1\">type<\/span> <span class=\"sy0\">!==<\/span> <span class=\"st0\">\"DEMO_ACTION\"<\/span><span class=\"br0\">)<\/span>\n<span class=\"br0\">}<\/span><span class=\"sy0\">;<\/span><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<p>The function will be invoked each time a new action is received. It\u2019ll receive the action as a parameter. The function should return <code>true<\/code> or <code>false<\/code> to indicate whether the action should be synchronised to other tabs. The example above will synchronise every action except <code>DEMO_ACTION<\/code>.<\/p>\n<h3 id=\"broadcast-channel-settings\"><span class=\"ez-toc-section\" id=\"Broadcast_Channel_Settings\"><\/span>Broadcast Channel Settings<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>You can change the name of the Broadcast Channel by setting the <code>channel<\/code> property. It defaults to <code>redux_state_sync<\/code>. You shouldn\u2019t usually need to change this unless you want to have two separate synchronisation routines.<\/p>\n<p>You can pass options to the Broadcast Channel abstraction library by setting <code>broadcastChannelOption<\/code>. This should be a configuration object accepted by the <a rel=\"nofollow noopener\" target=\"_blank\" href=\"https:\/\/github.com\/pubkey\/broadcast-channel\"><code>pubkey\/broadcast-channel<\/code> library<\/a>.<\/p>\n<p>You can use this to force a particular storage <a href=\"https:\/\/buradabiliyorum.com\/en\/category\/technology\/\" data-internallinksmanager029f6b8e52c=\"4\" title=\"Technology\" target=\"_blank\" rel=\"noopener\">technology<\/a> to be used. In this example, synchronisation will always occur via IndexedDB, even if the browser has native support for Broadcast Channels.<\/p>\n<div class=\"wp-geshi-highlight-wrap5\">\n<div class=\"wp-geshi-highlight-wrap4\">\n<div class=\"wp-geshi-highlight-wrap3\">\n<div class=\"wp-geshi-highlight-wrap2\">\n<div class=\"wp-geshi-highlight-wrap\">\n<div class=\"wp-geshi-highlight\">\n<div class=\"javascript\">\n<pre class=\"de1\"><span class=\"kw1\">const<\/span> config <span class=\"sy0\">=<\/span> <span class=\"br0\">{<\/span>\n    broadcastChannelOption<span class=\"sy0\">:<\/span> <span class=\"br0\">{<\/span>type<span class=\"sy0\">:<\/span> <span class=\"st0\">\"idb\"<\/span><span class=\"br0\">}<\/span>\n<span class=\"br0\">}<\/span><span class=\"sy0\">;<\/span><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<h2 id=\"integrating-with-redux-persist\"><span class=\"ez-toc-section\" id=\"Integrating_With_Redux-Persist\"><\/span>Integrating With Redux-Persist<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>You\u2019ll often want to use Redux State Sync in conjunction with Redux Persist. Redux Persist is a popular library which automatically persists your Redux store in the browser.<\/p>\n<p>When using Redux Persist, you don\u2019t need to use Redux Persist\u2019s <code>initStateWithPrevTab()<\/code> function. Use <code>initMessageListener()<\/code> instead, as the initial state will always be the persisted state provided by Redux Persist.<\/p>\n<p>Blacklist Redux Persist actions within your Redux State Sync configuration. These don\u2019t need to be synchronised across tabs. You should only sync changes that actually affect the store, rather than actions related to its lifecycle.<\/p>\n<div class=\"wp-geshi-highlight-wrap5\">\n<div class=\"wp-geshi-highlight-wrap4\">\n<div class=\"wp-geshi-highlight-wrap3\">\n<div class=\"wp-geshi-highlight-wrap2\">\n<div class=\"wp-geshi-highlight-wrap\">\n<div class=\"wp-geshi-highlight\">\n<div class=\"javascript\">\n<pre class=\"de1\"><span class=\"kw1\">const<\/span> config <span class=\"sy0\">=<\/span> <span class=\"br0\">{<\/span>\n    blacklist<span class=\"sy0\">:<\/span> <span class=\"br0\">[<\/span><span class=\"st0\">\"persist\/PERSIST\"<\/span><span class=\"sy0\">,<\/span> <span class=\"st0\">\"persist\/REHYDRATE\"<\/span><span class=\"br0\">]<\/span>\n<span class=\"br0\">}<\/span><span class=\"sy0\">;<\/span><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<h2 id=\"summary\"><span class=\"ez-toc-section\" id=\"Summary\"><\/span>Summary<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Redux State Sync lets you synchronise user actions across tabs. The applications are virtually boundless and are likely to improve the user experience. As users take actions on your site, they\u2019ll be im<a href=\"https:\/\/buradabiliyorum.com\/en\/category\/social-mediaa\/\" data-internallinksmanager029f6b8e52c=\"1\" title=\"Social Media\" target=\"_blank\" rel=\"noopener\">media<\/a>tely reflected in their other open tabs.<\/p>\n<p>The \u201cclassic\u201d use case is synchronising login and logout outcomes. There are other benefits too though, such as making incoming notifications available to all tabs, or synchronising client-side preferences like the user\u2019s selected UI theme.<\/p>\n<p>The <a rel=\"nofollow noopener\" target=\"_blank\" href=\"https:\/\/github.com\/aohua\/redux-state-sync\/blob\/master\/dist\/syncState.umd.min.js\">minified redux-state-sync library<\/a> weighs in at 19KB. With setup consisting of just a few extra lines of code, you should consider adding Redux State Sync to your next project. It lets you link tabs together into a cohesive whole, instead of having them exist as independent entities.\n<\/div>\n<blockquote><p><strong><span style=\"color: #ff6600;\">If you liked the article, do not forget to share it with your friends. Follow us on\u00a0<span style=\"color: #ff0000;\"><a style=\"color: #ff0000;\" href=\"https:\/\/news.google.com\/publications\/CAAqBwgKMLG0nwswvr63Aw\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Google News<\/a><\/span>\u00a0too, click on the star and choose us from your favorites.<\/span><\/strong><\/p><\/blockquote>\n<blockquote>\n<p style=\"text-align: center;\">For forums sites go to <span style=\"color: #ff9900;\"><a style=\"color: #ff9900;\" href=\"https:\/\/forum.buradabiliyorum.com\/\" target=\"_blank\" rel=\"noopener\">Forum.BuradaBiliyorum.Com<\/a><\/span><\/strong><\/p>\n<\/blockquote>\n<blockquote>\n<p style=\"text-align: center;\"><strong>If you want to read more like this article, you can visit our <span style=\"color: #ff9900;\"><a style=\"color: #ff9900;\" href=\"https:\/\/en.buradabiliyorum.com\/technology\/\" target=\"_blank\" rel=\"noopener\">Technology category.<\/a><\/span><\/strong><\/p>\n<\/blockquote>\n<p><span style=\"color: black;\"><a style=\"color: #ff9900;\" href=\"https:\/\/www.cloudsavvyit.com\/10517\/how-to-sync-a-redux-store-across-browser-tabs\/\" target=\"_blank\" rel=\"noopener\">Source<\/a><\/span><\/p>\n","protected":false},"excerpt":{"rendered":"<p>&#8220;#How to Sync a Redux Store Across Browser Tabs \u2013 CloudSavvy IT&#8221; Redux is a convenient way to manage state in complex web apps. Your Redux store isn\u2019t synced across tabs though, which can lead to some awkward scenarios. If the user logs out in one tab, it would be ideal for that action to&#8230;<\/p>\n","protected":false},"author":1,"featured_media":221138,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"fifu_image_url":"https:\/\/www.cloudsavvyit.com\/p\/uploads\/2021\/02\/99128fa6.jpg","fifu_image_alt":"","footnotes":""},"categories":[18],"tags":[],"class_list":["post-221137","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-technology"],"_links":{"self":[{"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/posts\/221137","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/comments?post=221137"}],"version-history":[{"count":0,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/posts\/221137\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/media\/221138"}],"wp:attachment":[{"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/media?parent=221137"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/categories?post=221137"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/tags?post=221137"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}