diff --git a/src/components/ProtectedRoute.tsx b/src/components/ProtectedRoute.tsx index e2cfaa2..482c7c8 100644 --- a/src/components/ProtectedRoute.tsx +++ b/src/components/ProtectedRoute.tsx @@ -1,12 +1,14 @@ -import { type ReactNode, Suspense, useState, useEffect } from 'react' +import { type ReactNode, Suspense, useState, useLayoutEffect } from 'react' import { Navigate, useLocation } from 'react-router-dom' import { useAuth } from '../contexts/AuthContext' import { PageLoader } from './PageLoader' // Mounts only once Suspense has resolved (chunk is ready). -// Signals the parent to hide the loader and reveal content. +// useLayoutEffect fires before the browser paints, so setState here causes a +// synchronous re-render — content becomes visible in the same paint with no +// intermediate loader flash for cached chunks. function ContentReady({ onReady }: { onReady: () => void }) { - useEffect(() => { + useLayoutEffect(() => { onReady() // eslint-disable-next-line react-hooks/exhaustive-deps }, []) @@ -19,9 +21,10 @@ export function ProtectedRoute({ children }: Props) { const { user, loading } = useAuth() const location = useLocation() - // On page refresh: loading starts true → contentReady=false → loader shows throughout. - // On in-app navigation: loading is already false → contentReady=true → no loader shown. - const [contentReady, setContentReady] = useState(() => !loading) + // Always start false so the loader covers any intermediate render state. + // For cached chunks, ContentReady's useLayoutEffect fires before the first + // paint and flips this synchronously — no visible flash. + const [contentReady, setContentReady] = useState(false) if (!loading && !user) { return diff --git a/src/pages/LoginPage.tsx b/src/pages/LoginPage.tsx index fa893e9..504e70c 100644 --- a/src/pages/LoginPage.tsx +++ b/src/pages/LoginPage.tsx @@ -19,7 +19,9 @@ export default function LoginPage() { useEffect(() => { if (loading) return - if (user) navigate('/write', { replace: true }) + if (user) { + import('./HomePage').then(() => navigate('/write', { replace: true })) + } }, [user, loading, navigate]) async function handleGoogleSignIn() {