I have a JavaScript file loaded by both my login page and dashboard page. It checks localStorage to decide whether the user has a valid session, then redirects logged-out users to index.html and logged-in users to dashboard.html. Instead, the browser keeps bouncing between the two pages. I suspect something is wrong with the session condition or the redirect logic. Here are the important parts:
const required_keys = ["Username","Account-Creation","Account-Type","Logged-In","Clients","Display-Name"];
const login_path = `${default_site_root}/index.html`;
const dashboard_path = `${default_site_root}/pages/dashboard/dashboard.html`;
function checkRequiredKeysExist() {
for (const key of required_keys) {
if (!localStorage.getItem(key)) return false;
}
return true;
}
function RedirectUser() {
const logged_in = localStorage.getItem("Logged-In");
const currentpath = window.location.pathname;
removeExtraKeys();
const is_valid_session = (logged_in === "true") && checkRequiredKeysExist();
if (!is_valid_session && (!currentpath.endsWith("index.html") || currentpath.endsWith("/"))) {
localStorage.clear();
window.location.replace(login_path);
return;
}
if (!currentpath.includes("dashboard.html")) {
window.location.replace(dashboard_path);
}
}
The script is included on both pages, and I have also tried changing the condition after receiving feedback, but the redirect loop still happens. What is the correct way to structure this logic and debug which condition is causing the loop?
3 Answers
There are two major logic problems. First, the session check must require the keys to exist. If you use `checkRequiredKeysExist() === false`, then a session is considered valid when the required keys are missing. Use `const hasSession = localStorage.getItem("Logged-In") === "true" && checkRequiredKeysExist();` instead.
Second, make sure the dashboard redirect is actually inside its `if` block. Without braces, only the next statement is conditional, so `window.location.replace(dashboard_path)` may run every time. The safest structure is:
`const hasSession = localStorage.getItem("Logged-In") === "true" && checkRequiredKeysExist();`
`const onLogin = currentpath.endsWith("/index.html") || currentpath.endsWith("/");`
`const onDashboard = currentpath.endsWith("/dashboard.html");`
`if (!hasSession) {`
` if (!onLogin) window.location.replace(login_path);`
` return;`
`}`
`if (!onDashboard) window.location.replace(dashboard_path);`
This makes the two session states mutually exclusive: invalid sessions stay on the login page, while valid sessions go to the dashboard.
Use the browser console to find out exactly why each page is redirecting. Put a log immediately before each `location.replace()` and print the values being tested:
`console.log({ currentpath, logged_in, hasRequiredKeys: checkRequiredKeysExist(), hasSession });`
Enable “Preserve log” in the developer tools so the messages remain visible after navigation. Then compare the values printed on the login page with those printed on the dashboard page. This usually reveals that one page sees `Logged-In` as something other than the exact string `"true"`, or that one of the required keys is missing or empty.
Also check that the login code writes every key in `required_keys` before redirecting. `localStorage` stores strings, so set the flag with `localStorage.setItem("Logged-In", "true")`, not a Boolean value that you later compare inconsistently.
Be careful with `removeExtraKeys()`. It deletes every localStorage entry that is not in your list, including data belonging to other parts of the same site. It is better to give your application keys a prefix and delete only keys belonging to this application.
Also, localStorage is only client-side state, not real authentication. It is fine for controlling the UI, but anything that must be protected should be checked by a server or backend rather than trusting a user-editable `Logged-In` value.

The `moved_user` variable cannot prevent a loop across pages. A redirect destroys the current page's JavaScript context, so the next page creates `moved_user` as `false` again. The real fix is correcting the conditions on both pages.