Skip to content

fix(navbar): eliminate auth button flash using useSyncExternalStore#4127

Merged
waleedlatif1 merged 2 commits intostagingfrom
fix/navbar-auth-flash
Apr 13, 2026
Merged

fix(navbar): eliminate auth button flash using useSyncExternalStore#4127
waleedlatif1 merged 2 commits intostagingfrom
fix/navbar-auth-flash

Conversation

@waleedlatif1
Copy link
Copy Markdown
Collaborator

Summary

  • Replaced useState(false) + useEffect setMounted with useSyncExternalStore to eliminate the auth button flash on the landing page navbar
  • getServerSnapshot: () => false ensures SSR and initial hydration agree (no mismatch), then client snapshot returns true immediately — no extra render cycle on client-side navigation
  • Extracted shouldShow = mounted && !isSessionPending to unify the condition across desktop and mobile button containers
  • Swapped invisible for opacity-0 pointer-events-none + transition-opacity duration-200 so buttons fade in cleanly once auth resolves instead of snapping
  • Added aria-hidden to both button containers while hidden so invisible buttons are removed from the accessibility tree
  • Bumped GitHub star count to 27.7k

Type of Change

  • Bug fix

Testing

Tested manually — no flash on page load, buttons fade in correctly for both authenticated and unauthenticated states

Checklist

  • Code follows project style guidelines
  • Self-reviewed my changes
  • Tests added/updated and passing
  • No new warnings introduced
  • I confirm that I have read and agree to the terms outlined in the Contributor License Agreement (CLA)

@cursor
Copy link
Copy Markdown

cursor bot commented Apr 13, 2026

PR Summary

Low Risk
Low risk UI-only change that adjusts navbar render/visibility timing during session loading; no auth logic or data handling is modified.

Overview
Prevents landing navbar auth CTAs from briefly flashing by switching the mounted check to useSyncExternalStore and gating both desktop and mobile CTA containers behind a shared shouldShow condition.

Updates hidden-state behavior to fade CTAs in via opacity/pointer-events with aria-hidden/inert while concealed, and bumps the GitHub star fallback display from 27.6k to 27.7k.

Reviewed by Cursor Bugbot for commit 73e1256. Configure here.

@vercel
Copy link
Copy Markdown

vercel bot commented Apr 13, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
docs Skipped Skipped Apr 13, 2026 5:48pm

Request Review

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Apr 13, 2026

Greptile Summary

This PR fixes the auth button flash on the landing page navbar by replacing the old useState(false) + useEffect mount pattern with useSyncExternalStore, which guarantees the SSR and hydration renders agree on mounted = false before transitioning to true synchronously during hydration. It also smooths the reveal with an opacity fade, improves accessibility using inert + aria-hidden, and bumps the GitHub star count to 27.7k.

Confidence Score: 5/5

Safe to merge — the useSyncExternalStore pattern is correct, previously-raised accessibility issues are resolved, and there are no P0/P1 findings.

All remaining findings are P2 or lower. The useSyncExternalStore implementation correctly uses getServerSnapshot to match SSR output and transitions synchronously to the client snapshot during hydration — eliminating the flash without an extra async render cycle. The inert+aria-hidden pairing (while slightly redundant) is harmless and improves cross-browser compatibility. Prior review concerns about aria-hidden="false" and keyboard focusability have been addressed.

No files require special attention.

Important Files Changed

Filename Overview
apps/sim/app/(landing)/components/navbar/navbar.tsx Core fix: replaces useState+useEffect mount pattern with useSyncExternalStore for SSR-safe hydration, adds shouldShow guard, opacity transition, inert+aria-hidden on both button containers. Implementation is correct and previously-flagged issues have been addressed.
apps/sim/app/(landing)/components/navbar/components/github-stars.tsx Trivial bump of INITIAL_STARS fallback from '27.6k' to '27.7k'.

Sequence Diagram

sequenceDiagram
    participant SSR as Server (SSR)
    participant Hydration as Client (Hydration)
    participant Client as Client (Post-Hydration)

    SSR->>SSR: getServerSnapshot() → false
    SSR->>SSR: mounted=false, shouldShow=false
    SSR->>SSR: Renders opacity-0 button containers

    Hydration->>Hydration: getServerSnapshot() → false (matches SSR)
    Hydration->>Hydration: React confirms hydration parity
    Hydration->>Hydration: Schedules re-render with getSnapshot()

    Client->>Client: getSnapshot() → true
    Client->>Client: mounted=true
    alt isSessionPending = true
        Client->>Client: shouldShow=false, buttons still opacity-0
        Client->>Client: Session resolves, isSessionPending=false
        Client->>Client: shouldShow=true, fade in 200ms transition
    else isSessionPending = false
        Client->>Client: shouldShow=true, fade in 200ms transition
    end
Loading

Reviews (2): Last reviewed commit: "fix(navbar): add inert and fix aria-hidd..." | Re-trigger Greptile

Copy link
Copy Markdown

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Autofix Details

Bugbot Autofix prepared a fix for the issue found in the latest run.

  • ✅ Fixed: Hidden buttons remain keyboard-focusable, violating WCAG accessibility
    • Added inert attribute to both desktop and mobile auth button containers when hidden, preventing keyboard focus on interactive elements while maintaining the opacity transition.

Create PR

Or push these changes by commenting:

@cursor push ccfa6da7ba
Preview (ccfa6da7ba)
diff --git a/apps/sim/app/(landing)/components/navbar/navbar.tsx b/apps/sim/app/(landing)/components/navbar/navbar.tsx
--- a/apps/sim/app/(landing)/components/navbar/navbar.tsx
+++ b/apps/sim/app/(landing)/components/navbar/navbar.tsx
@@ -215,6 +215,7 @@
 
           <div
             aria-hidden={!shouldShow}
+            inert={shouldShow ? undefined : ''}
             className={cn(
               'hidden items-center gap-2 pr-16 pl-5 transition-opacity duration-200 lg:flex',
               shouldShow ? 'opacity-100' : 'pointer-events-none opacity-0'
@@ -336,6 +337,7 @@
 
             <div
               aria-hidden={!shouldShow}
+              inert={shouldShow ? undefined : ''}
               className={cn(
                 'mt-auto flex flex-col gap-2.5 p-5 transition-opacity duration-200',
                 shouldShow ? 'opacity-100' : 'pointer-events-none opacity-0'

This Bugbot Autofix run was free. To enable autofix for future PRs, go to the Cursor dashboard.

@waleedlatif1
Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1
Copy link
Copy Markdown
Collaborator Author

@cursor review

Copy link
Copy Markdown

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 73e1256. Configure here.

@waleedlatif1 waleedlatif1 merged commit cfe5591 into staging Apr 13, 2026
12 checks passed
@waleedlatif1 waleedlatif1 deleted the fix/navbar-auth-flash branch April 13, 2026 18:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant