If you open the same application in multiple tabs on the same browser, sometimes it becomes really important to keep these tabs in sync. For example, think about your online banking portal. If you log in on one tab and then try to open the same portal in another tab, the first tab will often show a “session expired” message or automatically log you out.
That's a classic case of tab synchronization.
The problem I faced
In my case, the issue was auth syncing.
When the application was opened in multiple tabs, if the user logged out in one tab, the other tabs still tried to use the expired access token. Since the token was no longer valid, all API calls in those tabs failed until the user manually refreshed.
The solution
The idea is simple:
- Use localStorage as a shared state between tabs (since it is accessible across all the tabs of the same origin).
- Keep a special key (let's call it
changeInAuth
) in localStorage that updates whenever login or logout happens. - In every tab, listen for changes to this key using the
storage
event. When a change is detected, clear any invalid data from sessionStorage and reload the page so that the tabs fetches fresh tokens and user data.
Step 1: Add a storage event listener in App.tsx
useEffect(() => {
const handleLocalStorageChange = (event: StorageEvent) => {
// Check if the auth key changed
if (event.key === "changeInAuth") {
// Clear session data
sessionStorage.clear();
// Refresh the page
window.location.reload();
}
};
window.addEventListener("storage", handleLocalStorageChange);
// Always clean up event listeners
return () => {
window.removeEventListener("storage", handleLocalStorageChange);
};
}, []);
Here, we're telling the browser:
"If any tab updates the
changeInAuth
key in localStorage, reload this tab."
Step 2: Update localStorage during login
const login = async (userCreds) => {
try {
// Call authentication API
// Save tokens, user info, etc. in sessionStorage or cookies
// Trigger sync event for other tabs
localStorage.setItem("changeInAuth", Date.now().toString());
} catch (error) {
console.error("Login failed:", error);
}
};
Step 3: Update localStorage during logout
const logout = async () => {
// Call logout API
// Clear tokens, user info, and sessionStorage/cookies
// Trigger sync event for other tabs
localStorage.setItem("changeInAuth", Date.now().toString());
};
How it works
- Whenever login or logout happens, a unique timestamp is stored in localStorage under the key
changeInAuth
. - All tabs are listening for changes to this key.
- When a change is detected, tabs clear old session data and reload.
- After reload, they fetch fresh tokens and sync with the backend.
This way, the application can:
- Keep all tabs sync.
- Handle single-user sessions properly
- Automatically switch to the correct user when someone logs in/out.
Final thoughts
The storage
event is a very handy browser feature, and in many cases, a few lines of code are enough to solve what could otherwise be a very frustrating problem.
Top comments (0)