Skip to content

feat: add mobile navigation with hamburger menu#15

Merged
michellepace merged 10 commits intomainfrom
mobile-nav
Dec 19, 2025
Merged

feat: add mobile navigation with hamburger menu#15
michellepace merged 10 commits intomainfrom
mobile-nav

Conversation

@michellepace
Copy link
Owner

Summary

  • Add mobile hamburger menu with slide-out sheet drawer for navigation on screens <640px
  • Create route group architecture (with-right-sidebar / no-right-sidebar) preparing for future sidebar widgets
  • Add 6 placeholder pages (Community, Jobs, Tags, Profile, Ask Question, Collections) with Empty state component
  • Align design tokens (secondary, sidebar colours) with Figma specifications

Changes

Navigation

  • MobileNav component with Sheet drawer, conditional auth buttons (SignedIn/SignedOut)
  • NavLink component with active state gradient and icon inversion
  • ThemeLogo reusable component, nav links centralised in constants.ts
  • Desktop auth buttons hidden on mobile, shown in mobile menu instead

Route Architecture

  • Split app/(root) into (with-right-sidebar) and (no-right-sidebar) groups
  • Both layouts currently identical but ready for future differentiation

UI Components

  • Sheet component (Radix Dialog) for mobile drawer
  • Empty component for placeholder page states
  • soft and muted button variants
  • invert-colors utility for SVG icons

Styles

  • Separate --mobile-nav token from --sidebar for independent theming
  • Update --secondary and --sidebar colours to match Figma
  • Add --auth-bg CSS variable for auth layout background

Test plan

  • Lint and typecheck pass (npm run check)
  • Unit tests pass (npm run test:unit)
  • E2E tests pass — includes new mobile nav flow tests (npm run test:e2e)
  • Manual: Open mobile menu, navigate to each page, verify menu closes
  • Manual: Test signed-in vs signed-out states in mobile menu
  • Manual: Verify theme toggle works, active nav link shows gradient

Notes

  • Protected routes intentionally not implemented in this PR
  • Jobs page contains debug scaffolding for layout testing (intentional)

🤖 Generated with Claude Code

michellepace and others added 7 commits December 17, 2025 00:57
Navigation:

- Flatten navbar/index.tsx to navbar.tsx at navigation level

Styles:

- Move gradient CSS variables to top of :root block

Claude Code:

- Add plugin marketplace configs and enable feature-dev, shadcn-ui, skill-creator
- Reformat settings.json structure

Tidies folder structure and configuration ahead of mobile navigation feature work.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Documentation:
- Rename x_docs/own/ to x_docs/mine/ for consistency
- Add mobile navigation implementation guidance
- Add Next.js 16 caching/rendering explanation docs
- Remove unused screenshot images

Renames 9 markdown files from own/ to mine/ subdirectory. Adds three new docs:
mobile-nav build instructions referencing Figma designs and shadcn/ui Sheet
component, plus two complementary caching guides covering practical
implementation patterns and conceptual understanding of Next.js 16's new
Cache Components model.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Adds DevFlow description from root layout metadata to provide context about the
project purpose (Stack Overflow-style Q&A platform for developers).
Figma reference:

- Breakpoint analysis with annotated screenshot
- Route structure idea for right sidebar layouts

Project notes:

- Page spacing reference (padding vs margin, layout approach)
- Navigation architecture across mobile, rail, and sidebar contexts

Captures design decisions and technical reference for the mobile-nav feature
branch work.
Navigation:
- Add MobileNav component with hamburger menu triggering slide-out sheet
- Create NavLink component with active state gradient and icon inversion
- Extract ThemeLogo as reusable component, centralise nav links in constants.ts
- Hide desktop auth buttons on mobile, show in sheet with soft/muted variants

Route Architecture:
- Split routes into (with-right-sidebar) and (no-right-sidebar) groups
- Add placeholder pages: community, jobs, tags, profile, ask-question, collections
- Move auth layout centering and background to layout level

UI Components:
- Add Sheet component (Radix Dialog) for mobile drawer
- Add Empty component for placeholder page states
- Add soft and muted button variants, invert-colors utility
- Update secondary and sidebar colour tokens to match Figma

Testing:
- Add E2E tests for mobile navigation flow and keyboard accessibility

Mobile users can now access all pages via hamburger menu. Route groups prepare
the layout structure for future sidebar widgets.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Documents common shadcn CLI operations for listing, searching, viewing, and
adding components. Includes v0.dev registry syntax.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
CSS Variables:
- Add --mobile-nav token for mobile drawer background
- Adjust dark mode --sidebar to #0F1117 (lighter)
- Mobile nav uses #07080b in dark mode (darker, matches Figma)

Cleanup:
- Delete old.globals.css (unused legacy utility classes)

Separating the mobile nav background from the sidebar token allows each to be
themed independently. The mobile drawer now uses a darker background in dark
mode for better visual separation when open.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@vercel
Copy link

vercel bot commented Dec 18, 2025

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

Project Deployment Review Updated (UTC)
devflow Ready Ready Preview, Comment Dec 19, 2025 5:24am

@coderabbitai
Copy link

coderabbitai bot commented Dec 18, 2025

Summary by CodeRabbit

Release Notes

  • New Features

    • Mobile navigation with hamburger menu providing full-screen navigation panel on mobile devices.
    • Six new pages: Community, Jobs, Profile, Tags, Ask a Question, Collections.
  • UI/Visual Improvements

    • Enhanced visual styling with new colour tokens and gradients for improved consistency.
    • Improved theme logo and responsive layout adjustments for better spacing across all breakpoints.

✏️ Tip: You can customize this high-level summary in your review settings.

Walkthrough

This pull request implements mobile navigation infrastructure alongside responsive layout restructuring. It adds a mobile navigation sheet component, placeholder pages for community/jobs/tags/profile, new layout structures for right-sidebar routes, updated theming tokens, and fresh UI components (Sheet), whilst removing legacy styling.

Changes

Cohort / File(s) Change Summary
Configuration & Permissions
\.claude/settings\.json
Adjusted permission rules, added enabledPlugins and extraKnownMarketplaces configuration sections
Documentation
CLAUDE\.md, x_docs/figma/*, x_docs/mine/*
Added DevFlow descriptive content, shadcn/ui CLI section, and comprehensive guides on navigation breakpoints, page spacing, Next.js caching patterns, and mobile/rail navigation architecture
Authentication Layout
app/(auth)/layout\.tsx, app/(auth)/sign-in/[[\.\.\.sign-in]]/page\.tsx, app/(auth)/sign-up/[[\.\.\.sign-up]]/page\.tsx
Updated auth layout to use flexbox centering with responsive padding; removed wrapper divs from sign-in and sign-up pages
Root Layouts
app/(root)/(no-right-sidebar)/layout\.tsx, app/(root)/(with-right-sidebar)/layout\.tsx
Introduced new layout components for no-right-sidebar and with-right-sidebar route groups with responsive padding and structural comments
Root Pages – No Right Sidebar
app/(root)/(no-right-sidebar)/community/page\.tsx, app/(root)/(no-right-sidebar)/jobs/page\.tsx, app/(root)/(no-right-sidebar)/profile/page\.tsx, app/(root)/(no-right-sidebar)/tags/page\.tsx
Added placeholder page components rendering simple headings for community, jobs, profile, and tags routes
Root Pages – With Right Sidebar
app/(root)/(with-right-sidebar)/page\.tsx, app/(root)/(with-right-sidebar)/ask-question/page\.tsx, app/(root)/(with-right-sidebar)/collections/page\.tsx
Added home page with flexbox demonstration and placeholder pages for ask-question and collections
Navigation Components
components/navigation/constants\.ts, components/navigation/full-logo\.tsx, components/navigation/mobile-nav\.tsx, components/navigation/nav-link\.tsx, components/navigation/navbar\.tsx, components/navigation/theme-toggle\.tsx
Introduced navigation data constants, ThemeLogo component, MobileNav sheet-based component with Clerk integration, NavLink routing component, and updated Navbar to incorporate mobile navigation; adjusted theme toggle sizing
UI Components
components/ui/button\.tsx, components/ui/sheet\.tsx
Added soft and muted button variants; introduced complete Sheet component system wrapping Radix UI dialog primitives with configurable slide direction
Styling
app/globals\.css, app/old\.globals\.css
Added CSS tokens for mobile navigation, authentication background images, and primary gradients; updated secondary and sidebar colour values with Figma references; introduced .invert-colors utility; removed legacy globals file
Testing
e2e/mobile-nav-user-flow\.spec\.ts
Added end-to-end Playwright tests for mobile navigation flow covering link iteration, navigation assertions, menu closure behaviour, and overlay click interactions
Dependencies
package\.json
Added @radix-ui/react-dialog dependency

Sequence Diagram

sequenceDiagram
    participant User
    participant Mobile as Mobile Nav<br/>(Sheet)
    participant NavLink
    participant Clerk
    participant Router

    User->>Mobile: Tap hamburger icon
    Mobile->>Mobile: Open sheet, render NAV_LINKS
    
    alt User is signed out
        Mobile->>Clerk: Render SignInButton & SignUpButton
        User->>Clerk: Tap "Sign In" or "Sign Up"
        Clerk->>Router: Navigate to auth flow
    else User is signed in
        Mobile->>Clerk: Render SignOutButton
        User->>Clerk: Tap "Sign Out"
        Clerk->>Router: Redirect home
    end

    User->>NavLink: Tap navigation link
    NavLink->>Router: Navigate to route
    Router->>Mobile: Update active state, close sheet
    Mobile->>User: Sheet collapses (Menu icon returns)
Loading

Estimated Code Review Effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Areas requiring extra attention:

  • components/navigation/mobile-nav.tsx: Verify Clerk integration (SignedIn/SignedOut logic) and Sheet state management
  • components/ui/sheet.tsx: Review Radix UI dialog primitive wrapping, side-based positioning logic, and accessibility attributes
  • app/globals.css: Confirm CSS token naming consistency, colour accuracy against Figma references, and dark/light mode variants
  • e2e/mobile-nav-user-flow.spec.ts: Validate test coverage of overlay closure and viewport coordinate handling for 375×667 dimensions

Possibly Related PRs

Poem

🐰 A hopping celebration!

Mobile menus now dance and sway,
Sheets slide open when you play—
Links light up with Clerk's embrace,
Colours sing in every place,
Responsive joy in every breakpoint's trace!

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 3.57% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarises the primary change: adding mobile navigation with a hamburger menu, which is the core feature implemented across the changeset.
Description check ✅ Passed The description is comprehensive and directly related to the changeset, detailing mobile navigation, route architecture, UI components, styles, and test coverage.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch mobile-nav

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.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 11

📜 Review details

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fef98be and 887170b.

⛔ Files ignored due to path filters (4)
  • package-lock.json is excluded by !**/package-lock.json
  • x_docs/figma/nav-over-breakpoints.jpg is excluded by !**/*.jpg
  • x_docs/images/app_screenshot.jpg is excluded by !**/*.jpg
  • x_docs/images/github-social-thin.jpg is excluded by !**/*.jpg
📒 Files selected for processing (32)
  • .claude/settings.json (1 hunks)
  • CLAUDE.md (2 hunks)
  • app/(auth)/layout.tsx (1 hunks)
  • app/(auth)/sign-in/[[...sign-in]]/page.tsx (1 hunks)
  • app/(auth)/sign-up/[[...sign-up]]/page.tsx (1 hunks)
  • app/(root)/(no-right-sidebar)/community/page.tsx (1 hunks)
  • app/(root)/(no-right-sidebar)/jobs/page.tsx (1 hunks)
  • app/(root)/(no-right-sidebar)/layout.tsx (1 hunks)
  • app/(root)/(no-right-sidebar)/profile/page.tsx (1 hunks)
  • app/(root)/(no-right-sidebar)/tags/page.tsx (1 hunks)
  • app/(root)/(with-right-sidebar)/ask-question/page.tsx (1 hunks)
  • app/(root)/(with-right-sidebar)/collections/page.tsx (1 hunks)
  • app/(root)/(with-right-sidebar)/layout.tsx (1 hunks)
  • app/globals.css (7 hunks)
  • app/old.globals.css (0 hunks)
  • components/navigation/constants.ts (1 hunks)
  • components/navigation/full-logo.tsx (1 hunks)
  • components/navigation/mobile-nav.tsx (1 hunks)
  • components/navigation/nav-link.tsx (1 hunks)
  • components/navigation/navbar.tsx (2 hunks)
  • components/navigation/theme-toggle.tsx (1 hunks)
  • components/ui/button.tsx (1 hunks)
  • components/ui/empty.tsx (1 hunks)
  • components/ui/sheet.tsx (1 hunks)
  • e2e/mobile-nav-user-flow.spec.ts (1 hunks)
  • package.json (1 hunks)
  • x_docs/figma/nav-over-breakpoints.md (1 hunks)
  • x_docs/mine/2025-12-17-make-mobile-nav.md (1 hunks)
  • x_docs/mine/2025-12-17-page-spacing.md (1 hunks)
  • x_docs/mine/caching-explained-1.md (1 hunks)
  • x_docs/mine/caching-explained-2.md (1 hunks)
  • x_docs/mine/nav_mobile_sidebar-and-rail.md (1 hunks)
💤 Files with no reviewable changes (1)
  • app/old.globals.css
🧰 Additional context used
📓 Path-based instructions (5)
app/**/*.{tsx,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Only add 'use client' directive when interactivity is needed

Files:

  • app/(root)/(with-right-sidebar)/layout.tsx
  • app/(root)/(no-right-sidebar)/community/page.tsx
  • app/(root)/(with-right-sidebar)/collections/page.tsx
  • app/(root)/(no-right-sidebar)/profile/page.tsx
  • app/(root)/(with-right-sidebar)/ask-question/page.tsx
  • app/(root)/(no-right-sidebar)/layout.tsx
  • app/(auth)/sign-up/[[...sign-up]]/page.tsx
  • app/(root)/(no-right-sidebar)/jobs/page.tsx
  • app/(root)/(no-right-sidebar)/tags/page.tsx
  • app/(auth)/layout.tsx
  • app/(auth)/sign-in/[[...sign-in]]/page.tsx
**/*.{tsx,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Avoid manual useMemo/useCallback unless profiling shows need

Files:

  • app/(root)/(with-right-sidebar)/layout.tsx
  • app/(root)/(no-right-sidebar)/community/page.tsx
  • app/(root)/(with-right-sidebar)/collections/page.tsx
  • app/(root)/(no-right-sidebar)/profile/page.tsx
  • components/navigation/mobile-nav.tsx
  • app/(root)/(with-right-sidebar)/ask-question/page.tsx
  • components/navigation/nav-link.tsx
  • app/(root)/(no-right-sidebar)/layout.tsx
  • components/navigation/theme-toggle.tsx
  • components/ui/sheet.tsx
  • components/ui/empty.tsx
  • app/(auth)/sign-up/[[...sign-up]]/page.tsx
  • app/(root)/(no-right-sidebar)/jobs/page.tsx
  • components/navigation/navbar.tsx
  • app/(root)/(no-right-sidebar)/tags/page.tsx
  • components/navigation/full-logo.tsx
  • components/ui/button.tsx
  • app/(auth)/layout.tsx
  • app/(auth)/sign-in/[[...sign-in]]/page.tsx
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Always use @/ import aliases, even for sibling imports (e.g., @/app/fonts not ./fonts)

Files:

  • app/(root)/(with-right-sidebar)/layout.tsx
  • app/(root)/(no-right-sidebar)/community/page.tsx
  • app/(root)/(with-right-sidebar)/collections/page.tsx
  • app/(root)/(no-right-sidebar)/profile/page.tsx
  • components/navigation/constants.ts
  • components/navigation/mobile-nav.tsx
  • app/(root)/(with-right-sidebar)/ask-question/page.tsx
  • components/navigation/nav-link.tsx
  • app/(root)/(no-right-sidebar)/layout.tsx
  • components/navigation/theme-toggle.tsx
  • components/ui/sheet.tsx
  • components/ui/empty.tsx
  • app/(auth)/sign-up/[[...sign-up]]/page.tsx
  • app/(root)/(no-right-sidebar)/jobs/page.tsx
  • components/navigation/navbar.tsx
  • app/(root)/(no-right-sidebar)/tags/page.tsx
  • e2e/mobile-nav-user-flow.spec.ts
  • components/navigation/full-logo.tsx
  • components/ui/button.tsx
  • app/(auth)/layout.tsx
  • app/(auth)/sign-in/[[...sign-in]]/page.tsx
app/(auth)/**/*.{tsx,ts}

📄 CodeRabbit inference engine (CLAUDE.md)

Auth routes should be structured as app/(auth)/sign-in/[[...sign-in]] and app/(auth)/sign-up/[[...sign-up]]

Files:

  • app/(auth)/sign-up/[[...sign-up]]/page.tsx
  • app/(auth)/layout.tsx
  • app/(auth)/sign-in/[[...sign-in]]/page.tsx
**/*.{css,postcss}

📄 CodeRabbit inference engine (CLAUDE.md)

Use Tailwind v4 @import syntax (@import "tailwindcss") instead of @tailwind directives

Files:

  • app/globals.css
🧠 Learnings (6)
📚 Learning: 2025-12-10T20:20:46.607Z
Learnt from: michellepace
Repo: michellepace/devflow PR: 7
File: components/navigation/navbar/index.tsx:1-12
Timestamp: 2025-12-10T20:20:46.607Z
Learning: Clerk's Next.js components (SignedIn, SignedOut, SignInButton, SignUpButton, UserButton) from clerk/nextjs can be used inside Server Components without adding 'use client' in the consuming component. They manage client/server boundary internally. When reviewing code, prefer omitting 'use client' in server components that render these Clerk components and avoid introducing client directives solely for these components. This guideline helps maintain server/server boundary and reduce client bundle size.

Applied to files:

  • app/(root)/(with-right-sidebar)/layout.tsx
  • app/(root)/(no-right-sidebar)/community/page.tsx
  • app/(root)/(with-right-sidebar)/collections/page.tsx
  • app/(root)/(no-right-sidebar)/profile/page.tsx
  • components/navigation/mobile-nav.tsx
  • app/(root)/(with-right-sidebar)/ask-question/page.tsx
  • components/navigation/nav-link.tsx
  • app/(root)/(no-right-sidebar)/layout.tsx
  • components/navigation/theme-toggle.tsx
  • components/ui/sheet.tsx
  • components/ui/empty.tsx
  • app/(auth)/sign-up/[[...sign-up]]/page.tsx
  • app/(root)/(no-right-sidebar)/jobs/page.tsx
  • components/navigation/navbar.tsx
  • app/(root)/(no-right-sidebar)/tags/page.tsx
  • components/navigation/full-logo.tsx
  • components/ui/button.tsx
  • app/(auth)/layout.tsx
  • app/(auth)/sign-in/[[...sign-in]]/page.tsx
📚 Learning: 2025-12-14T22:58:06.155Z
Learnt from: CR
Repo: michellepace/devflow PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-14T22:58:06.155Z
Learning: Applies to components/auth/clerk-signin.tsx : Place Sign In component at components/auth/clerk-signin.tsx as a client component with theme-aware logo

Applied to files:

  • components/navigation/mobile-nav.tsx
  • app/(auth)/sign-up/[[...sign-up]]/page.tsx
  • components/navigation/navbar.tsx
  • x_docs/mine/2025-12-17-make-mobile-nav.md
  • components/navigation/full-logo.tsx
  • app/(auth)/layout.tsx
  • app/(auth)/sign-in/[[...sign-in]]/page.tsx
📚 Learning: 2025-12-14T22:58:06.155Z
Learnt from: CR
Repo: michellepace/devflow PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-14T22:58:06.155Z
Learning: Applies to components/auth/clerk-signup.tsx : Place Sign Up component at components/auth/clerk-signup.tsx with static logo

Applied to files:

  • components/navigation/mobile-nav.tsx
  • app/(auth)/sign-up/[[...sign-up]]/page.tsx
  • components/navigation/navbar.tsx
  • x_docs/mine/2025-12-17-make-mobile-nav.md
  • components/navigation/full-logo.tsx
  • app/(auth)/layout.tsx
  • app/(auth)/sign-in/[[...sign-in]]/page.tsx
📚 Learning: 2025-12-10T20:20:54.402Z
Learnt from: michellepace
Repo: michellepace/devflow PR: 7
File: components/navigation/navbar/index.tsx:1-12
Timestamp: 2025-12-10T20:20:54.402Z
Learning: Clerk's Next.js components (SignedIn, SignedOut, SignInButton, SignUpButton, UserButton) exported from clerk/nextjs are designed to work in Server Components without requiring a "use client" directive in the consuming component, as they handle the client/server boundary internally with their own directives.

Applied to files:

  • package.json
  • CLAUDE.md
  • x_docs/mine/2025-12-17-make-mobile-nav.md
📚 Learning: 2025-12-14T22:58:06.155Z
Learnt from: CR
Repo: michellepace/devflow PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-14T22:58:06.155Z
Learning: Applies to components/clerk-provider.tsx : ClerkProvider component should be in components/clerk-provider.tsx and apply shadcn theme + Inter font

Applied to files:

  • package.json
  • app/(auth)/sign-up/[[...sign-up]]/page.tsx
  • components/navigation/navbar.tsx
  • x_docs/mine/2025-12-17-make-mobile-nav.md
  • app/(auth)/sign-in/[[...sign-in]]/page.tsx
📚 Learning: 2025-12-14T22:58:06.155Z
Learnt from: CR
Repo: michellepace/devflow PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-14T22:58:06.155Z
Learning: Applies to app/(auth)/**/*.{tsx,ts} : Auth routes should be structured as app/(auth)/sign-in/[[...sign-in]] and app/(auth)/sign-up/[[...sign-up]]

Applied to files:

  • app/(auth)/sign-up/[[...sign-up]]/page.tsx
  • x_docs/mine/2025-12-17-make-mobile-nav.md
  • app/(auth)/layout.tsx
  • app/(auth)/sign-in/[[...sign-in]]/page.tsx
🧬 Code graph analysis (16)
app/(root)/(no-right-sidebar)/community/page.tsx (1)
components/ui/empty.tsx (4)
  • Empty (98-98)
  • EmptyHeader (99-99)
  • EmptyTitle (100-100)
  • EmptyDescription (101-101)
app/(root)/(with-right-sidebar)/collections/page.tsx (1)
components/ui/empty.tsx (4)
  • Empty (98-98)
  • EmptyHeader (99-99)
  • EmptyTitle (100-100)
  • EmptyDescription (101-101)
app/(root)/(no-right-sidebar)/profile/page.tsx (1)
components/ui/empty.tsx (4)
  • Empty (98-98)
  • EmptyHeader (99-99)
  • EmptyTitle (100-100)
  • EmptyDescription (101-101)
components/navigation/constants.ts (1)
components/navigation/nav-link.tsx (1)
  • NavLink (15-41)
components/navigation/mobile-nav.tsx (5)
components/ui/sheet.tsx (6)
  • Sheet (131-131)
  • SheetTrigger (132-132)
  • SheetContent (134-134)
  • SheetTitle (137-137)
  • SheetDescription (138-138)
  • SheetClose (133-133)
components/ui/button.tsx (1)
  • Button (65-65)
components/navigation/full-logo.tsx (1)
  • ThemeLogo (15-27)
components/navigation/constants.ts (2)
  • NAV_LINKS (7-19)
  • NavLink (1-5)
components/navigation/nav-link.tsx (1)
  • NavLink (15-41)
app/(root)/(with-right-sidebar)/ask-question/page.tsx (1)
components/ui/empty.tsx (4)
  • Empty (98-98)
  • EmptyHeader (99-99)
  • EmptyTitle (100-100)
  • EmptyDescription (101-101)
components/navigation/nav-link.tsx (2)
components/navigation/constants.ts (1)
  • NavLink (1-5)
lib/utils.ts (1)
  • cn (4-6)
components/navigation/theme-toggle.tsx (1)
components/ui/button.tsx (1)
  • Button (65-65)
components/ui/sheet.tsx (1)
lib/utils.ts (1)
  • cn (4-6)
components/ui/empty.tsx (1)
lib/utils.ts (1)
  • cn (4-6)
app/(auth)/sign-up/[[...sign-up]]/page.tsx (1)
components/auth/clerk-signup.tsx (1)
  • ClerkSignUp (3-13)
app/(root)/(no-right-sidebar)/jobs/page.tsx (1)
components/ui/empty.tsx (4)
  • Empty (98-98)
  • EmptyHeader (99-99)
  • EmptyTitle (100-100)
  • EmptyDescription (101-101)
components/navigation/navbar.tsx (3)
components/navigation/full-logo.tsx (1)
  • ThemeLogo (15-27)
components/navigation/theme-toggle.tsx (1)
  • ThemeToggle (8-32)
components/navigation/mobile-nav.tsx (1)
  • MobileNav (26-112)
e2e/mobile-nav-user-flow.spec.ts (1)
components/navigation/constants.ts (1)
  • NAV_LINKS (7-19)
components/navigation/full-logo.tsx (1)
lib/utils.ts (1)
  • cn (4-6)
app/(auth)/sign-in/[[...sign-in]]/page.tsx (1)
components/auth/clerk-signin.tsx (1)
  • ClerkSignIn (6-26)
🪛 LanguageTool
x_docs/mine/caching-explained-1.md

[style] ~387-~387: The double modal “needed Cached” is nonstandard (only accepted in certain dialects). Consider “to be Cached”.
Context: ...nt** is automatic - no work needed 3. Cached content uses 'use cache' + `cacheLi...

(NEEDS_FIXED)

x_docs/mine/caching-explained-2.md

[style] ~12-~12: To form a complete sentence, be sure to include a subject.
Context: ...e sees the same (questions list, tags). Can be cached. 3. Personal Content - Da...

(MISSING_IT_THERE)


[locale-violation] ~15-~15: In British English, the spelling ‘anymore’ is sometimes considered incorrect. Did you mean “any more”?
Context: ... each layer**. Next.js 16 doesn't guess anymore - you explicitly mark what should be ca...

(ANYMORE)


[style] ~30-~30: To form a complete sentence, be sure to include a subject.
Context: ...2. "How fresh does it need to be?" - Can be minutes/hours old → Cache with a t...

(MISSING_IT_THERE)


[style] ~117-~117: Would you like to use the Oxford spelling “Personalized”? The spelling ‘Personalised’ is also correct.
Context: ...on every single request. Good for: Personalised content, auth-dependent data, real-time...

(OXFORD_SPELLING_Z_NOT_S)


[style] ~133-~133: Would you like to use the Oxford spelling “personalized”? The spelling ‘personalised’ is also correct.
Context: ... You get: Fast initial paint, then personalised content appears. --- ## DevOverflow R...

(OXFORD_SPELLING_Z_NOT_S)


[style] ~217-~217: To form a complete sentence, be sure to include a subject or ‘there’.
Context: ...validation** Refreshing cached content. Can be time-based ("every hour") or on-dema...

(MISSING_IT_THERE)

x_docs/mine/2025-12-17-page-spacing.md

[style] ~222-~222: Would you like to use the Oxford spelling “visualization”? The spelling ‘visualisation’ is also correct.
Context: ...ean up | Remove debug content added for visualisation | | spacing-explained.md | Create | D...

(OXFORD_SPELLING_Z_NOT_S)


[style] ~241-~241: Would you like to use the Oxford spelling “visualization”? The spelling ‘visualisation’ is also correct.
Context: ...peat(100)}content that were added for visualisation testing. Keep only the` compon...

(OXFORD_SPELLING_Z_NOT_S)

x_docs/mine/2025-12-17-make-mobile-nav.md

[style] ~35-~35: Would you like to use the Oxford spelling “Centralized”? The spelling ‘Centralised’ is also correct.
Context: ...* components/navigation/constants.ts Centralised nav links used by both mobile nav (now)...

(OXFORD_SPELLING_Z_NOT_S)


[uncategorized] ~174-~174: Possible missing comma found.
Context: ...cumentation For additional guidance on styling Clerk components: - Search Index for l...

(AI_HYDRA_LEO_MISSING_COMMA)

x_docs/figma/nav-over-breakpoints.md

[uncategorized] ~3-~3: Possible missing comma found.
Context: ...It is my goal to pragmatically align to this following elegant and best practices. ...

(AI_HYDRA_LEO_MISSING_COMMA)


[style] ~60-~60: Would you like to use the Oxford spelling “organize”? The spelling ‘organise’ is also correct.
Context: ...f perhaps it is I know best practice to organise routes to support this three-column lay...

(OXFORD_SPELLING_Z_NOT_S)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Run E2E Tests
🔇 Additional comments (42)
CLAUDE.md (1)

3-3: DevFlow description is clear and contextual.

The project overview is well-written, establishes the project's purpose, and matches the existing tone. It appropriately uses British English throughout ("around the world" rather than Americanisms). This addition helps onboard new contributors quickly.

x_docs/mine/caching-explained-1.md (2)

1-12: Excellent introduction to Cache Components model.

The contrast between implicit caching (old) and explicit opt-in caching (new) clearly sets reader expectations. This provides valuable context for the rest of the document.


146-158: DevOverflow route recommendations are well-aligned with PR architecture.

The suggested caching strategies for each route (questions, tags, jobs, community, profile, collections, ask-question) align logically with the route groups added in this PR (with-right-sidebar, no-right-sidebar). The distinction between static/cached/dynamic appropriately reflects user-specific versus shared content patterns.

x_docs/mine/caching-explained-2.md (4)

1-40: Clear conceptual framework for caching decisions.

The three-question approach (Is it the same for everyone? How fresh does it need to be? Does it need cookies/headers?) and the decision tree provide an excellent mental model for developers to determine caching strategy. This complements the practical examples in caching-explained-1.md well.


137-149: Route recommendations align well with PR scope.

The DevOverflow routes table mirrors and reinforces the recommendations from caching-explained-1.md. The routes match the placeholder pages and route groups introduced in this PR, providing helpful context for future implementation.


153-195: Practical guidance section enhances usability.

The "What to Ask Claude Code For" section bridges documentation and developer workflow by providing concrete prompts. This is particularly useful for a platform integrating AI assistance and helps developers translate caching concepts into actionable requests.


199-224: Comprehensive glossary improves clarity.

The glossary clearly defines key terminology (Static Shell, Streaming, Suspense, PPR, Cache Components, Revalidation, Cache Tag, Server Action). This supports readers who may be new to Next.js 16 concepts and reduces ambiguity across both documentation files.

.claude/settings.json (3)

67-69: Good security practice.

Explicitly denying read access to .env and .envrc files prevents accidental exposure of secrets during development assistance.


70-77: LGTM.

The enabled plugins (shadcn-ui, feature-dev) align with the project's UI component library and development workflow.


78-97: Marketplace configuration sources are acceptable but warrant documentation.

Adding custom marketplaces through extraKnownMarketplaces follows the standard Claude Code pattern documented in official guidance. The three marketplace sources are:

  • anthropics/claude-plugins-official – an Anthropic-managed directory of high-quality Claude Code Plugins
  • lackeyjb/playwright-skill – a legitimate community plugin enabling Playwright browser automation
  • michellepace/my-claude-plugins – a personal marketplace following the community-driven pattern documented by Anthropic

The extraKnownMarketplaces configuration in .claude/settings.json is the standard way to set up automatic marketplace installation for team projects. Consider adding a comment to the configuration explaining why these marketplaces are required for development workflows.

package.json (1)

27-27: LGTM!

The Radix Dialog dependency supports the new Sheet component for mobile navigation, and the version range is consistent with other Radix dependencies in the project.

app/(auth)/sign-in/[[...sign-in]]/page.tsx (1)

4-8: LGTM!

The simplified structure correctly delegates layout responsibilities to the parent (auth)/layout.tsx. The component remains a server component without an unnecessary 'use client' directive, as Clerk components manage the client/server boundary internally.

components/navigation/theme-toggle.tsx (2)

14-16: LGTM!

The placeholder size increase maintains visual consistency during the mounting phase and aligns with the updated button sizing.


19-31: LGTM!

The icon-lg size variant aligns with the broader navigation UI updates introduced in this PR.

app/(root)/(with-right-sidebar)/collections/page.tsx (1)

1-17: LGTM!

The placeholder page follows the consistent Empty component pattern and correctly remains a server component without unnecessary client directives.

app/(auth)/sign-up/[[...sign-up]]/page.tsx (1)

4-8: LGTM!

The structure mirrors the sign-in page simplification and correctly maintains the server component boundary. Layout responsibilities are appropriately delegated to the parent layout.

app/(root)/(with-right-sidebar)/ask-question/page.tsx (1)

1-17: LGTM!

The placeholder page follows the consistent Empty component pattern established across the PR and correctly remains a server component.

components/navigation/full-logo.tsx (2)

3-5: LGTM!

Centralising logo dimensions as constants eliminates magic numbers and improves maintainability.


15-27: The component's syntax is correct and follows Tailwind v4 standards. The bg-(image:--logo-full-themed) class properly uses the documented type-hint syntax to reference the CSS variable. No changes needed—the code is valid.

components/ui/button.tsx (1)

24-26: LGTM!

The new soft and muted button variants are well-implemented with appropriate dark mode support and hover states. These variants provide good visual hierarchy for the mobile navigation authentication buttons.

components/navigation/constants.ts (1)

1-19: LGTM!

The centralised navigation constants are well-structured. The use of as const satisfies readonly NavLink[] provides excellent type safety whilst maintaining the constant nature of the array. This shared data source will simplify maintaining consistency between mobile and desktop navigation.

components/navigation/nav-link.tsx (3)

17-18: LGTM! Well-considered active route logic.

The isActive logic correctly handles the edge case where the home route ("/") shouldn't match all routes. By checking route.length > 1 for startsWith, it ensures only the root path uses strict equality matching.


36-36: The invert-colors utility is already defined in your global styles (app/globals.css) as .invert-colors { @apply invert dark:invert-0; }. No further action required.


27-27: Tailwind v4 CSS variable syntax is correct.

The syntax bg-(image:--gradient-primary) correctly follows Tailwind CSS v4 conventions. The (image:) type hint is the standard way to disambiguate background-image properties when using CSS variables, and the --gradient-primary variable is properly defined in your globals.css. No changes needed.

components/navigation/mobile-nav.tsx (3)

46-49: Excellent accessibility implementation!

The visually hidden SheetTitle and SheetDescription provide important context for screen reader users whilst maintaining the desired visual design. This demonstrates good inclusive design practices.


60-68: LGTM! Well-structured navigation with automatic sheet closure.

Wrapping each NavLink in SheetClose ensures the mobile navigation sheet closes automatically when a user navigates to a new page, providing an intuitive user experience.


72-86: LGTM! Appropriate use of Clerk components.

The SignedIn wrapper correctly gates the sign-out functionality, and the custom button implementation maintains consistent styling with the rest of the navigation whilst providing proper logout functionality.

components/navigation/navbar.tsx (2)

10-11: LGTM! Proper import aliases used.

The imports correctly use @/ aliases as required by the coding guidelines, maintaining consistency across the codebase.

Based on coding guidelines.


42-57: LGTM! Well-implemented responsive navigation strategy.

The desktop authentication controls are appropriately hidden on mobile (hidden sm:flex), whilst the MobileNav component handles mobile-specific navigation with proper visibility controls. This clean separation ensures a consistent experience across breakpoints without code duplication.

x_docs/mine/2025-12-17-make-mobile-nav.md (1)

1-254: Documentation file — no code review needed.

This documentation file provides comprehensive guidance for the mobile navigation implementation. The minor style issues flagged by static analysis (British vs. American spelling, possible missing comma) are acceptable in documentation and don't affect functionality.

app/globals.css (1)

32-32: LGTM! Well-structured theme token additions.

The new CSS tokens are properly declared in both light and dark themes with appropriate OKLCH values. The separation of --mobile-nav from --sidebar enables independent theming, and the --auth-bg token provides a clean way to handle background images. The .invert-colors utility is well-documented and addresses the technical constraint of external SVG files not responding to currentColor.

Also applies to: 60-65, 75-75, 90-90, 98-98, 102-102, 115-115, 130-130, 138-138, 142-142, 197-203

app/(auth)/layout.tsx (1)

1-7: LGTM! Clean token-based background implementation.

The layout correctly uses the new bg-(image:--auth-bg) token with proper flexbox centering. The Tailwind v4 arbitrary value syntax is correctly applied, and the responsive padding scales appropriately across breakpoints.

app/(root)/(no-right-sidebar)/community/page.tsx (1)

1-17: Clean placeholder implementation.

The page correctly remains a server component (no unnecessary 'use client' directive) and uses the Empty UI primitives appropriately. The structure is consistent with other placeholder pages in the PR.

app/(root)/(no-right-sidebar)/profile/page.tsx (1)

1-17: Clean placeholder implementation.

The page correctly remains a server component and follows the established Empty state pattern. Implementation is consistent with other placeholder pages.

x_docs/mine/nav_mobile_sidebar-and-rail.md (1)

1-426: Comprehensive navigation architecture documentation.

This documentation provides clear guidance on the navigation system's component structure, variant mechanics, and responsive behaviour across breakpoints. The visual breakdowns and code examples will be valuable for future development and maintenance.

x_docs/figma/nav-over-breakpoints.md (1)

1-138: Clear breakpoint and layout documentation.

The documentation effectively describes the navigation behaviour across five breakpoints and proposes a sensible route group structure using (with-right-sidebar) and (without-right-sidebar). This approach aligns with Next.js best practices for layout composition.

e2e/mobile-nav-user-flow.spec.ts (1)

7-27: Excellent test coverage for mobile navigation flow.

The test comprehensively validates the complete user journey: opening the menu, verifying link visibility, navigating, and confirming the menu closes automatically. The iteration pattern ensures all navigation links are tested consistently.

x_docs/mine/2025-12-17-page-spacing.md (1)

1-273: Excellent documentation with clear visual aids and practical guidance.

This documentation provides comprehensive coverage of the page spacing strategy with helpful ASCII diagrams, practical code examples, and a clear implementation plan. The before/after comparisons and Tailwind class reference table make it easy to understand both the problem and the solution.

The British English spelling ("visualisation") is correct for the project's language setting.

components/ui/sheet.tsx (4)

1-23: Clean component wrappers with proper client directive.

The type-only React import is a good practice for tree-shaking, and the "use client" directive is correctly applied since Radix Dialog requires client-side interactivity. All wrapper components follow a consistent pattern with data-slot attributes for potential styling hooks.


25-45: Appropriate overlay styling with subtle backdrop effects.

The overlay implementation uses a subtle semi-transparent background (5% opacity) with extra small blur, which provides visual separation without being obtrusive. The animation classes properly handle open/closed states.


84-128: Layout and text components follow best practices.

SheetHeader and SheetFooter provide sensible layout defaults with appropriate spacing. SheetTitle and SheetDescription properly wrap Radix primitives to maintain accessibility features (ARIA attributes and focus management). The mt-auto on SheetFooter ensures it sticks to the bottom of the sheet when used in a flex container.


130-139: Clean public API with appropriate encapsulation.

The exports correctly expose only the public-facing components whilst keeping SheetPortal and SheetOverlay as internal implementation details. This provides a clean API surface for consumers.

michellepace and others added 3 commits December 19, 2025 09:09
Placeholder pages:
- Replace Empty component usage with simple <h1> titles
- Affected: community, collections, tags, ask-question, profile, jobs

Root page:
- Add flexbox visualisation for layout debugging (grow vs flex-none)
- Include header/footer boundary markers with primary background

Cleanup:
- Delete components/ui/empty.tsx (104 lines, no longer used)

Reduces complexity in placeholder pages while keeping a useful spacing debug
tool on the root page. The Empty component can be re-added via shadcn CLI when
actual empty states are needed.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Change list item from descriptive to imperative phrasing
- Add explicit subjects to sentence fragments
- Use British English "any more" instead of American "anymore"

Addresses CodeRabbit review comments for grammatical consistency across both
caching explanation documents.
Test Implementation:

- Replace keyboard Escape with overlay click to match test name
- Calculate click position dynamically from viewport width
- Target far-right edge (width - 10px) to avoid sheet content area

The test claimed to verify "clicks outside" behaviour but was pressing Escape. Now it
genuinely tests click-outside by targeting the visible overlay area. Dynamic positioning
prevents brittleness if viewport or sheet width changes.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

📜 Review details

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 887170b and 4d77b38.

📒 Files selected for processing (10)
  • app/(root)/(no-right-sidebar)/community/page.tsx (1 hunks)
  • app/(root)/(no-right-sidebar)/jobs/page.tsx (1 hunks)
  • app/(root)/(no-right-sidebar)/profile/page.tsx (1 hunks)
  • app/(root)/(no-right-sidebar)/tags/page.tsx (1 hunks)
  • app/(root)/(with-right-sidebar)/ask-question/page.tsx (1 hunks)
  • app/(root)/(with-right-sidebar)/collections/page.tsx (1 hunks)
  • app/(root)/(with-right-sidebar)/page.tsx (1 hunks)
  • e2e/mobile-nav-user-flow.spec.ts (1 hunks)
  • x_docs/mine/caching-explained-1.md (1 hunks)
  • x_docs/mine/caching-explained-2.md (1 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
app/**/*.{tsx,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Only add 'use client' directive when interactivity is needed

Files:

  • app/(root)/(no-right-sidebar)/jobs/page.tsx
  • app/(root)/(with-right-sidebar)/collections/page.tsx
  • app/(root)/(with-right-sidebar)/ask-question/page.tsx
  • app/(root)/(no-right-sidebar)/profile/page.tsx
  • app/(root)/(no-right-sidebar)/tags/page.tsx
  • app/(root)/(no-right-sidebar)/community/page.tsx
  • app/(root)/(with-right-sidebar)/page.tsx
**/*.{tsx,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Avoid manual useMemo/useCallback unless profiling shows need

Files:

  • app/(root)/(no-right-sidebar)/jobs/page.tsx
  • app/(root)/(with-right-sidebar)/collections/page.tsx
  • app/(root)/(with-right-sidebar)/ask-question/page.tsx
  • app/(root)/(no-right-sidebar)/profile/page.tsx
  • app/(root)/(no-right-sidebar)/tags/page.tsx
  • app/(root)/(no-right-sidebar)/community/page.tsx
  • app/(root)/(with-right-sidebar)/page.tsx
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Always use @/ import aliases, even for sibling imports (e.g., @/app/fonts not ./fonts)

Files:

  • app/(root)/(no-right-sidebar)/jobs/page.tsx
  • e2e/mobile-nav-user-flow.spec.ts
  • app/(root)/(with-right-sidebar)/collections/page.tsx
  • app/(root)/(with-right-sidebar)/ask-question/page.tsx
  • app/(root)/(no-right-sidebar)/profile/page.tsx
  • app/(root)/(no-right-sidebar)/tags/page.tsx
  • app/(root)/(no-right-sidebar)/community/page.tsx
  • app/(root)/(with-right-sidebar)/page.tsx
🧠 Learnings (1)
📚 Learning: 2025-12-10T20:20:46.607Z
Learnt from: michellepace
Repo: michellepace/devflow PR: 7
File: components/navigation/navbar/index.tsx:1-12
Timestamp: 2025-12-10T20:20:46.607Z
Learning: Clerk's Next.js components (SignedIn, SignedOut, SignInButton, SignUpButton, UserButton) from clerk/nextjs can be used inside Server Components without adding 'use client' in the consuming component. They manage client/server boundary internally. When reviewing code, prefer omitting 'use client' in server components that render these Clerk components and avoid introducing client directives solely for these components. This guideline helps maintain server/server boundary and reduce client bundle size.

Applied to files:

  • app/(root)/(no-right-sidebar)/jobs/page.tsx
  • app/(root)/(with-right-sidebar)/collections/page.tsx
  • app/(root)/(with-right-sidebar)/ask-question/page.tsx
  • app/(root)/(no-right-sidebar)/profile/page.tsx
  • app/(root)/(no-right-sidebar)/tags/page.tsx
  • app/(root)/(no-right-sidebar)/community/page.tsx
  • app/(root)/(with-right-sidebar)/page.tsx
🧬 Code graph analysis (1)
e2e/mobile-nav-user-flow.spec.ts (1)
components/navigation/constants.ts (1)
  • NAV_LINKS (7-19)
🪛 LanguageTool
x_docs/mine/caching-explained-2.md

[style] ~117-~117: Would you like to use the Oxford spelling “Personalized”? The spelling ‘Personalised’ is also correct.
Context: ...on every single request. Good for: Personalised content, auth-dependent data, real-time...

(OXFORD_SPELLING_Z_NOT_S)


[style] ~133-~133: Would you like to use the Oxford spelling “personalized”? The spelling ‘personalised’ is also correct.
Context: ... You get: Fast initial paint, then personalised content appears. --- ## DevOverflow R...

(OXFORD_SPELLING_Z_NOT_S)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Run E2E Tests
🔇 Additional comments (9)
x_docs/mine/caching-explained-2.md (1)

1-248: Excellent conceptual reference — comprehensive and accurate.

This document accurately reflects Next.js 16's Cache Components model, which uses the 'use cache' directive and centres around explicit, opt-in caching (unlike the implicit caching in previous versions). The three-layer mental model (Shell, Shared Content, Personal Content), the decision tree, and the DevOverflow route mappings provide practical, actionable guidance. The past review feedback on sentence fragments and British English phrasing has been well addressed.

The LanguageTool hints suggesting American spelling variants (lines 117, 133) can safely be ignored — your use of British English "Personalised" is correct and consistent throughout.

One minor stylistic note for British English convention: consider using em-dashes (—) instead of regular hyphens (-) for parenthetical statements (e.g., line 15: "doesn't guess any more — you explicitly mark..." and line 30: "can be minutes or hours old — cache with a time limit").

x_docs/mine/caching-explained-1.md (1)

1-395: Comprehensive and technically accurate documentation.

The document accurately describes Cache Components, the 'use cache' directive, and explicit opt-in caching behaviour in Next.js 16. The practical examples for cached public content (RecentQuestions, PopularTags), dynamic personalised content, and cache invalidation via server actions are well-structured and demonstrate real-world patterns appropriate for DevOverflow. The migration guidance from ISR and force-dynamic to the new model is clear and helpful.

The code examples correctly use revalidateTag() with the required cacheLife profile as the second argument (e.g., revalidateTag('blog-posts', 'max')), reflecting Next.js 16 API changes.

app/(root)/(with-right-sidebar)/ask-question/page.tsx (1)

1-3: LGTM! Clean placeholder implementation.

The page correctly remains a server component and provides a simple heading placeholder. The implementation aligns with Next.js 15 server component patterns.

app/(root)/(with-right-sidebar)/collections/page.tsx (1)

1-3: LGTM! Clean placeholder implementation.

The page correctly remains a server component and provides a simple heading placeholder.

e2e/mobile-nav-user-flow.spec.ts (2)

7-27: LGTM! Comprehensive navigation test.

The test correctly iterates through all navigation links, verifies visibility, navigation behaviour, and menu closure after each navigation. The implementation is thorough and follows Playwright best practices.


29-43: LGTM! Past issue resolved.

The previous review flagged a mismatch between the test name and implementation. This has been correctly addressed—the test now actually clicks outside via the overlay coordinates, matching the test name "mobile menu closes when user clicks outside".

app/(root)/(no-right-sidebar)/jobs/page.tsx (1)

1-3: LGTM! Past issue resolved.

The previous review flagged debug scaffolding that should be removed. This has been correctly addressed—the page now contains only a clean placeholder heading without any debug code.

app/(root)/(no-right-sidebar)/profile/page.tsx (1)

1-3: LGTM! Clean placeholder implementation.

The page correctly remains a server component and provides a simple heading placeholder.

app/(root)/(no-right-sidebar)/tags/page.tsx (1)

1-3: LGTM! Clean placeholder implementation.

The page correctly remains a server component and provides a simple heading placeholder.

Comment on lines +1 to +3
export default function CommunityPage() {
return <h1>Community</h1>;
}
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

LGTM! Consider extracting placeholder helper.

The page correctly remains a server component and provides a simple heading placeholder. However, this pattern is duplicated across six placeholder pages (AskQuestionPage, CollectionsPage, CommunityPage, JobsPage, ProfilePage, TagsPage).

🔎 Optional: Extract a reusable placeholder helper to reduce duplication

If you'd like to reduce duplication, consider creating a helper:

// lib/create-placeholder-page.tsx
export function createPlaceholderPage(title: string) {
  return function PlaceholderPage() {
    return <h1>{title}</h1>;
  };
}

Then each page becomes:

import { createPlaceholderPage } from "@/lib/create-placeholder-page";

export default createPlaceholderPage("Community");

This is optional for temporary scaffolding; the current approach is acceptable.

🤖 Prompt for AI Agents
In app/(root)/(no-right-sidebar)/community/page.tsx lines 1-3: this placeholder
H1 is duplicated across six similar pages; extract a reusable helper to reduce
duplication by adding a new helper file (e.g., lib/create-placeholder-page.tsx)
that exports a factory function taking a title and returning a server component
that renders the H1, then update this page to import that factory and export the
created placeholder for "Community" instead of the inline component; keep files
as server components and ensure the helper is typed/exported for reuse.

Comment on lines +1 to +31
const Home = () => (
<>
<h1>Hello Root page with heading H1</h1>

{/* Header boundary marker */}
<div className="mt-8 bg-primary/30 p-4">HEADER: {"words ".repeat(50)}</div>

{/* Flexbox demo: grow vs flex-none */}
<div className="my-8 flex gap-4 border-2 border-dashed border-primary p-4">
{/* Fixed width - won't grow */}
<div className="flex h-24 w-24 flex-none items-center justify-center rounded-lg border-2 border-dashed border-primary bg-sky-500/20 text-sm font-medium">
flex-none
</div>

{/* Grows to fill available space */}
<div className="flex h-24 grow items-center justify-center rounded-lg border-2 border-dashed border-primary bg-indigo-500/30 text-sm font-medium">
grow
</div>

{/* Fixed width - won't grow */}
<div className="flex h-24 w-24 flex-none items-center justify-center rounded-lg border-2 border-dashed border-primary bg-sky-500/20 text-sm font-medium">
flex-none
</div>
</div>

{/* Footer boundary marker */}
<div className="bg-primary/30 p-4">FOOTER: {"words ".repeat(50)}</div>
</>
);

export default Home;
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Remove debug scaffolding before merging.

The page contains obvious debug/test code including repeated words, visual debug borders, explicit layout markers, and testing banners. Whilst the PR notes acknowledge this scaffolding exists, debug code should not be committed to the main branch.

🔎 Apply this diff to replace with a proper placeholder:
-const Home = () => (
-  <>
-    <h1>Hello Root page with heading H1</h1>
-
-    {/* Header boundary marker */}
-    <div className="mt-8 bg-primary/30 p-4">HEADER: {"words ".repeat(50)}</div>
-
-    {/* Flexbox demo: grow vs flex-none */}
-    <div className="my-8 flex gap-4 border-2 border-dashed border-primary p-4">
-      {/* Fixed width - won't grow */}
-      <div className="flex h-24 w-24 flex-none items-center justify-center rounded-lg border-2 border-dashed border-primary bg-sky-500/20 text-sm font-medium">
-        flex-none
-      </div>
-
-      {/* Grows to fill available space */}
-      <div className="flex h-24 grow items-center justify-center rounded-lg border-2 border-dashed border-primary bg-indigo-500/30 text-sm font-medium">
-        grow
-      </div>
-
-      {/* Fixed width - won't grow */}
-      <div className="flex h-24 w-24 flex-none items-center justify-center rounded-lg border-2 border-dashed border-primary bg-sky-500/20 text-sm font-medium">
-        flex-none
-      </div>
-    </div>
-
-    {/* Footer boundary marker */}
-    <div className="bg-primary/30 p-4">FOOTER: {"words ".repeat(50)}</div>
-  </>
-);
+const Home = () => <h1>Home</h1>;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const Home = () => (
<>
<h1>Hello Root page with heading H1</h1>
{/* Header boundary marker */}
<div className="mt-8 bg-primary/30 p-4">HEADER: {"words ".repeat(50)}</div>
{/* Flexbox demo: grow vs flex-none */}
<div className="my-8 flex gap-4 border-2 border-dashed border-primary p-4">
{/* Fixed width - won't grow */}
<div className="flex h-24 w-24 flex-none items-center justify-center rounded-lg border-2 border-dashed border-primary bg-sky-500/20 text-sm font-medium">
flex-none
</div>
{/* Grows to fill available space */}
<div className="flex h-24 grow items-center justify-center rounded-lg border-2 border-dashed border-primary bg-indigo-500/30 text-sm font-medium">
grow
</div>
{/* Fixed width - won't grow */}
<div className="flex h-24 w-24 flex-none items-center justify-center rounded-lg border-2 border-dashed border-primary bg-sky-500/20 text-sm font-medium">
flex-none
</div>
</div>
{/* Footer boundary marker */}
<div className="bg-primary/30 p-4">FOOTER: {"words ".repeat(50)}</div>
</>
);
export default Home;
const Home = () => <h1>Home</h1>;
export default Home;
🤖 Prompt for AI Agents
In app/(root)/(with-right-sidebar)/page.tsx lines 1-31, the file contains debug
scaffolding (repeated "words", header/footer markers, dashed borders, and
flexbox demo blocks) that should be removed before merging; delete the visual
testing markup and repeated text and replace it with a minimal production
placeholder (e.g., a single H1 and a short descriptive paragraph or empty
container) while preserving the component signature and default export, and
ensure no leftover test classes or comments remain.

Comment on lines +385 to +389
1. **Enable Cache Components** in `next.config.ts`
2. **Static content** is automatic - no work needed
3. **Use** `'use cache'` + `cacheLife()` for cached content
4. **Dynamic content** wraps in `<Suspense>`
5. **Invalidate** with `updateTag()` (immediate) or `revalidateTag()` (background)
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major

Standardise list structure for parallel readability.

The summary list mixes grammatical patterns: item 1 starts with an imperative ("Enable"), items 3 and 5 use imperatives ("Use", "Invalidate"), but item 2 switches to a descriptive statement ("Static content is automatic"). For consistency, rewrite all five items to follow the same grammatical structure. An imperative pattern works best here:

🔎 Suggested improvement
  1. **Enable Cache Components** in `next.config.ts`
- 2. **Static content** is automatic - no work needed
- 3. **Use** `'use cache'` + `cacheLife()` for cached content
+ 2. **Keep static content automatic** — no extra setup needed
+ 3. **Use `'use cache'` + `cacheLife()`** for cached content
  4. **Dynamic content** wraps in `<Suspense>`
  5. **Invalidate** with `updateTag()` (immediate) or `revalidateTag()` (background)

Note: Also updated hyphens to em-dashes for British English convention.

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In x_docs/mine/caching-explained-1.md around lines 385 to 389, the five-list
items mix grammatical styles; rewrite them so all items use the same imperative
structure for parallel readability and change hyphens to em-dashes per British
English; e.g., convert item 2 to an imperative like "Enable automatic static
content" (or "Treat static content as automatic") and adjust punctuation so each
item follows the same verb-first form and uses em-dashes where needed.

@michellepace michellepace merged commit f8fc08a into main Dec 19, 2025
7 checks passed
@michellepace michellepace deleted the mobile-nav branch December 19, 2025 05:32
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