Skip to content

refactor: landing page separation, code review fixes, architecture cleanup - #31

Merged
holkexyz merged 10 commits into
mainfrom
staging
Apr 7, 2026
Merged

refactor: landing page separation, code review fixes, architecture cleanup#31
holkexyz merged 10 commits into
mainfrom
staging

Conversation

@holkexyz

@holkexyz holkexyz commented Apr 7, 2026

Copy link
Copy Markdown
Member

Summary

Architecture: Landing page separation

  • Move landing page from / to /welcome with middleware redirect for unauthenticated users
  • / is now purely the profile dashboard — no dual-rendering, no CSS hacks
  • Consolidate two footers into one global Footer component
  • Remove has-session class hack, certified_logged_in hint cookie, landing-ssr wrapper
  • Add client-side redirect to /welcome on sign-out or expired session

Code review fixes (10-reviewer audit)

  • Security: Sanitize error messages in auth API routes, wrap CSRF URL parsing in try/catch, invalidate existing session before creating new one
  • Accessibility: Skip navigation link, aria-describedby + aria-invalid on inputs, aria-haspopup/aria-expanded on navbar dropdowns, focus trapping in modals (useFocusTrap hook)
  • Performance: IntersectionObserver pauses orbiting logos animation when off-screen, SVGO optimization of guilloche SVG (167KB → 137KB)
  • CSS: Remove duplicate @keyframes spin, fix 100vw100% on mobile modals, remove unused CSS variables, standardize warning colors to CSS variables
  • Dead code: Delete unused faq.tsx, ready-cta.tsx, 3 unused guilloche SVGs
  • Error handling: Redis operations wrapped in try/catch with logging, profile seeding failures logged

Other

  • Fix feedback button flying off screen when footer is scrolled past
  • Add certified-hero-1200x630.png OG image and icon.png favicon

Test plan

  • Visit / unauthenticated → redirects to /welcome with landing page
  • Visit / authenticated → profile dashboard renders
  • Sign out → redirects to /welcome
  • Sign in from /welcome → lands on / dashboard
  • /welcome renders landing page with transparent navbar and footer
  • /about, /terms, /privacy render with app footer
  • Tab through sign-in modal → focus stays trapped
  • Tab key on page → skip nav link appears
  • Feedback button stays above footer on all pages
  • npm run build passes

🤖 Generated with Claude Code

Summary by CodeRabbit

Release Notes

  • New Features

    • New dedicated welcome page with optimized landing experience
    • Enhanced keyboard navigation with skip-to-main-content link
    • Improved form accessibility with better labels and error messaging
    • Focus trapping in modals for keyboard users
  • Bug Fixes

    • Better authentication error handling and session management
  • Documentation

    • Added SEO and AI visibility audit report

holkexyz and others added 9 commits April 7, 2026 10:51
…cleanup

Phase 1 - Quick wins:
- Delete dead code: faq.tsx, ready-cta.tsx, 3 unused guilloche SVGs
- Optimize guilloche_02.svg with SVGO (167KB → 137KB)
- Remove duplicate @Keyframes spin definition
- Fix 100vw → 100% on mobile modals (prevents horizontal overflow)

Phase 2 - Security:
- Sanitize error messages in auth API routes (no internal error leakage)
- Wrap CSRF URL parsing in try/catch (prevents 500 on malformed Origin)
- Invalidate existing session before creating new one (prevents fixation)

Phase 3 - SSR flash-of-content:
- Inline script checks session cookie and adds .has-session class to <html>
- CSS hides .landing-ssr when .has-session present (no flash for auth users)
- Remove fragile querySelector DOM manipulation from home-client.tsx

Phase 4 - Accessibility:
- Add skip navigation link (visible on focus)
- Add aria-describedby + aria-invalid to Input and Textarea components
- Add aria-haspopup + aria-expanded to navbar dropdown buttons
- Add focus trapping to sign-in and feedback modals (new useFocusTrap hook)

Phase 5 - Error handling:
- Wrap Redis operations in try/catch with structured logging
- Log profile seeding failures instead of silently swallowing

Phase 6 - Performance:
- Add IntersectionObserver to pause orbiting logos animation when off-screen

Phase 7 - CSS cleanup:
- Remove unused --color-info and --color-outline variables
- Add --color-warning-bg/border/text variables, replace hardcoded hex values

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The certified_session cookie is httpOnly, so the inline script couldn't
read it. Add a certified_logged_in hint cookie (non-sensitive, non-httpOnly)
that the client JS can check to hide the landing page before hydration.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Added footerRect.bottom > 0 check so the button only adjusts when the
footer is actually visible from below, not when scrolled above viewport.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…al footer

Both footers shared the .landing-footer class, so the feedback button
adjusted position on all pages. Now uses #landing-footer ID to target
only the landing page footer.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Landing page now lives at /welcome. Middleware redirects unauthenticated
users from / to /welcome. Homepage is purely the profile dashboard.

- Create src/middleware.ts: redirects / → /welcome when no session cookie
- Create src/app/welcome/page.tsx: landing page with metadata + JSON-LD
- Create src/app/welcome/layout.tsx: sets navbar to transparent variant
- Simplify page.tsx: profile dashboard only, no landing content
- Simplify home-client.tsx: remove navbar variant and has-session hacks
- Simplify footer.tsx: hide on /welcome instead of auth-conditional
- Simplify app-shell.tsx: pathname check instead of auth state check
- Remove inline cookie-check script from layout.tsx
- Remove .has-session CSS hack from globals.css
- Remove certified_logged_in hint cookie from session.ts
- Update sitemap.ts and llms.txt to reference /welcome

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Fall back to .landing-footer class selector when #landing-footer ID
isn't found, so the button avoids overlapping the global footer on
app pages too.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
… page

The landing page no longer needs its own inline footer — the global
Footer component from layout.tsx now renders on all pages including
/welcome. Removed the pathname check, the #landing-footer ID, and
the Link import from landing-page.tsx.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ails

Handles edge case where middleware lets the user through (cookie exists)
but the server-side session is expired or invalid. HomeClient now
redirects to /welcome instead of showing a blank page.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…sion

Calling router.replace() during render is unreliable. Moved to useEffect
that triggers when isLoading=false and isAuthenticated=false, properly
handling sign-out and expired session edge cases.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@vercel

vercel Bot commented Apr 7, 2026

Copy link
Copy Markdown
Contributor

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

Project Deployment Actions Updated (UTC)
certified-app Ready Ready Preview, Comment Apr 7, 2026 9:39pm

Request Review

@coderabbitai

coderabbitai Bot commented Apr 7, 2026

Copy link
Copy Markdown

Caution

Review failed

Pull request was closed or merged during review

📝 Walkthrough

Walkthrough

This PR restructures the application's routing and homepage architecture by migrating the landing page from / to /welcome, implementing authentication-based routing middleware, enhancing accessibility through focus traps and skip navigation, and refining session handling with improved error logging and validation.

Changes

Cohort / File(s) Summary
Homepage Migration
src/app/page.tsx, src/app/welcome/page.tsx, src/app/welcome/layout.tsx, src/app/sitemap.ts, public/llms.txt, GEO-AUDIT-REPORT.md
Moves landing page from / to /welcome with full SEO metadata, JSON-LD structured data (SoftwareApplication, FAQPage), and navbar transparency control; simplifies homepage to redirect clients; updates sitemap and llms.txt to point to new welcome URL.
Authentication & Routing Middleware
src/middleware.ts, src/app/api/auth/callback-handler/route.ts, src/app/api/auth/login/route.ts
Adds server middleware enforcing certified_session cookie check on /, redirecting unauthenticated users to /welcome; updates auth routes with improved error messaging (generic "Authentication failed" text), session deletion before creation, and console logging for debugging.
Session & Security
src/lib/auth/session.ts, src/lib/auth/csrf.ts
Wraps Redis operations in try/catch blocks with error logging; CSRF validation now catches URL parsing failures with 403 response; session deletion suppresses errors to allow cleanup regardless of Redis state.
Layout & Navigation
src/app/layout.tsx, src/components/layout/app-shell.tsx, src/components/layout/navbar.tsx, src/components/layout/footer.tsx
Adds skip-nav link in root layout; AppShell now gates shell rendering on /welcome path instead of auth state; Navbar gains ARIA attributes (aria-haspopup, aria-expanded) for interactive controls; Footer removes auth-dependent rendering logic.
Landing Page Components
src/components/landing/home-client.tsx, src/components/landing/landing-page.tsx, src/components/landing/orbiting-logos.tsx, src/components/landing/sections/faq.tsx, src/components/landing/sections/ready-cta.tsx
Home client now redirects unauthenticated users to /welcome instead of managing navbar variant; landing page footer removed; orbiting logos add off-screen detection via IntersectionObserver to pause animation; FAQ and ReadyCta sections removed (moved/consolidated into welcome page).
Accessibility & Forms
src/app/globals.css, src/hooks/use-focus-trap.ts, src/components/ui/sign-in-modal.tsx, src/components/ui/feedback-modal.tsx, src/components/ui/input.tsx, src/components/ui/textarea.tsx
Adds .skip-nav styling for keyboard-accessible skip link; new useFocusTrap hook traps focus within modals on Tab/Shift+Tab; modals integrated with focus trap; Input/Textarea components gain proper label association (htmlFor), ID generation via useId, and ARIA attributes (aria-invalid, aria-describedby); warning color CSS variables added and applied throughout.

Sequence Diagram

sequenceDiagram
    participant Client as Client Browser
    participant Middleware as Next.js Middleware
    participant Server as Server Routes
    participant Session as Redis/Session

    Client->>Middleware: GET / (without certified_session)
    Middleware->>Middleware: Check for certified_session cookie
    Middleware->>Client: Redirect to /welcome
    
    Client->>Server: GET /welcome
    Server->>Server: Render landing page + SEO metadata + JSON-LD
    Server->>Client: Return welcome page HTML
    
    Client->>Server: POST /api/auth/login (credentials)
    Server->>Session: createSession() with try/catch
    Session-->>Server: Session created or error logged
    Server->>Server: Log error if session creation fails
    Server->>Client: Return auth callback URL
    
    Client->>Server: GET /api/auth/callback-handler
    Server->>Session: deleteSession() (suppress errors)
    Server->>Session: createSession()
    Server->>Client: Set certified_session cookie + redirect to /
    
    Client->>Middleware: GET / (with certified_session)
    Middleware->>Middleware: Session cookie found
    Middleware->>Client: NextResponse.next() - proceed to page
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • PR #29: Modifies the same SEO/crawl infrastructure, metadata configuration, JSON-LD setup, and homepage rendering structure (page.tsx, sitemap, llms.txt), making it directly related to the homepage migration work.
  • PR #19: Updates the same layout and navigation components (app-shell, navbar, footer, home-client, globals.css) with overlapping structural and behavioral changes to the UI layer.

Poem

🐰 Hop, hop, hooray! Welcome routes now guide the way,
Focus traps keep users neat, skip-nav makes journeys sweet,
Sessions logged with grace and care, auth flows clean and fair,
Landing moves from root to rest, accessibility's the best! ✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 15.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: refactoring the landing page to a separate /welcome route, fixing code review issues, and performing architectural cleanup across authentication, accessibility, and styling.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch staging

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@holkexyz
holkexyz merged commit 15570ff into main Apr 7, 2026
2 checks passed
@coderabbitai coderabbitai Bot mentioned this pull request Jul 30, 2026
7 tasks
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