Show the landing page at / for signed-out visitors
The bare domain rendered Dashboard, so an anonymous visitor to the front door was held on the spinner and then redirected to Google — the marketing page was only reachable by knowing the /LandingPage URL. Key the decision off appParams.token rather than the resolved auth state so it settles synchronously, and the first paint is the landing page instead of a spinner waiting on a bootstrap request that can only redirect them away. A signed-in user still gets Dashboard. Also treat auth_required on / as signed out. Reaching that branch there means a token existed but is expired or revoked, and redirecting would trap the front door in a login bounce. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
19
src/App.jsx
19
src/App.jsx
@@ -63,6 +63,11 @@ const isPublicRoute = (pathname) => {
|
|||||||
return PUBLIC_ROUTES.has(normalized);
|
return PUBLIC_ROUTES.has(normalized);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// The bare domain is the front door, so it can't be allowed to bounce anonymous
|
||||||
|
// visitors to Google — signed out it shows the marketing page, signed in it shows
|
||||||
|
// the dashboard as before.
|
||||||
|
const ROOT_PATH = '/';
|
||||||
|
|
||||||
const AuthenticatedApp = () => {
|
const AuthenticatedApp = () => {
|
||||||
const { isLoadingAuth, isLoadingPublicSettings, authError, isAuthenticated, navigateToLogin } = useAuth();
|
const { isLoadingAuth, isLoadingPublicSettings, authError, isAuthenticated, navigateToLogin } = useAuth();
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
@@ -78,6 +83,14 @@ const AuthenticatedApp = () => {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Decided on the token rather than on the resolved auth state, so it settles
|
||||||
|
// synchronously: a visitor with no session gets the marketing page on the first
|
||||||
|
// paint instead of watching a spinner for a bootstrap request whose only
|
||||||
|
// possible outcome, for them, is a redirect away.
|
||||||
|
if (location.pathname === ROOT_PATH && !appParams.token) {
|
||||||
|
return <LandingPage />;
|
||||||
|
}
|
||||||
|
|
||||||
// Show loading spinner while checking app public settings or auth
|
// Show loading spinner while checking app public settings or auth
|
||||||
if (isLoadingPublicSettings || isLoadingAuth) {
|
if (isLoadingPublicSettings || isLoadingAuth) {
|
||||||
return (
|
return (
|
||||||
@@ -92,6 +105,12 @@ const AuthenticatedApp = () => {
|
|||||||
if (authError.type === 'user_not_registered') {
|
if (authError.type === 'user_not_registered') {
|
||||||
return <UserNotRegisteredError />;
|
return <UserNotRegisteredError />;
|
||||||
} else if (authError.type === 'auth_required') {
|
} else if (authError.type === 'auth_required') {
|
||||||
|
// Reaching here on the root path means a token existed but is no longer
|
||||||
|
// good — expired, revoked, or for another app. Treating that as signed out
|
||||||
|
// keeps the front door open instead of trapping it in a login redirect.
|
||||||
|
if (location.pathname === ROOT_PATH) {
|
||||||
|
return <LandingPage />;
|
||||||
|
}
|
||||||
// Redirect to login automatically
|
// Redirect to login automatically
|
||||||
navigateToLogin();
|
navigateToLogin();
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
Reference in New Issue
Block a user