How do you stop SSR hydration from flashing the wrong user state at the edge?

What’s up everyone? I’m wiring up SSR + edge rendering for a Next.js-ish app, and I’m trying to avoid a nasty flicker where the server renders “logged out” but the client immediately hydrates into “logged in”, so the header swaps and analytics double-fire.

export async function getServerProps(req) {
  const token = req.cookies.session;
  const user = token ? await fetchUser(token) : null;
  return { user };
}

function Header({ user }) {
  const [clientUser, setClientUser] = useState(user);

  useEffect(() => {
    fetch("/api/me", { credentials: "include" })
      .then(r => r.ok ? r.json() : null)
      .then(setClientUser);
  }, []);

  return <div>{clientUser ? "Welcome" : "Sign in"}</div>;
}

In real life the edge cache sometimes serves a stale logged-out HTML shell, and then hydration “corrects” it; what’s the cleanest pattern to prevent the UI swap and duplicate side effects without killing caching?

1 Like