Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Jan 27, 2026

Next.js build fails when prerendering pages containing header-bar component. The SidebarTrigger calls useSidebar() which throws when no SidebarProvider exists in the context tree.

Changes

  • Modified useSidebar() to return safe defaults instead of throwing when provider is missing
  • Extracted DEFAULT_SIDEBAR_STATE constant for consistency

Implementation

// Before: Hard failure during SSR
function useSidebar() {
  const context = React.useContext(SidebarContext)
  if (!context) {
    throw new Error("useSidebar must be used within a SidebarProvider.")
  }
  return context
}

// After: Graceful degradation
const DEFAULT_SIDEBAR_STATE: SidebarContextProps = {
  state: "expanded",
  open: true,
  setOpen: () => {},
  // ... other no-op defaults
}

function useSidebar() {
  const context = React.useContext(SidebarContext)
  return context ?? DEFAULT_SIDEBAR_STATE
}

This allows components using sidebar hooks to render during static generation while maintaining full functionality when wrapped in a provider.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • fonts.googleapis.com
    • Triggering command: /usr/local/bin/node node /home/REDACTED/work/objectui/objectui/apps/site/node_modules/.bin/../next/dist/bin/next build (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Original prompt

拉取请求: #234

19:14:54.168
19:14:54.202
Creating an optimized production build ...
19:15:19.702
✓ Compiled successfully in 25.1s
19:15:19.703
Running TypeScript ...
19:15:24.379
Collecting page data using 3 workers ...
19:15:25.305
Generating static pages using 3 workers (0/307) ...
19:15:25.848
Component type "toggle-group" is already registered. Overwriting.
19:15:25.849
Component type "table" is already registered. Overwriting.
19:15:25.880
Component type "toggle-group" is already registered. Overwriting.
19:15:25.881
Component type "table" is already registered. Overwriting.
19:15:26.122
Generating static pages using 3 workers (76/307)
19:15:28.423
Generating static pages using 3 workers (153/307)
19:15:30.079
Error occurred prerendering page "/docs/components/navigation/header-bar". Read more: https://nextjs.org/docs/messages/prerender-error
19:15:30.082
Error: useSidebar must be used within a SidebarProvider.
19:15:30.082
at Tt (.next/server/chunks/ssr/3f0f8b0f..js:77:57878)
19:15:30.082
at (.next/server/chunks/ssr/3f0f8b0f..js:77:61519) {
19:15:30.082
digest: '4175081625'
19:15:30.083
}
19:15:30.083
Export encountered an error on /docs/[[...slug]]/page: /docs/components/navigation/header-bar, exiting the build.
19:15:30.135
⨯ Next.js build worker exited with code: 1 and signal: null
19:15:30.246
 ELIFECYCLE  Command failed with exit code 1.
19:15:30.269
Error: Command "pnpm --filter '../../packages/*' -r build && pnpm build" exited with 1


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

@vercel
Copy link

vercel bot commented Jan 27, 2026

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

Project Deployment Review Updated (UTC)
objectui-site Ready Ready Preview, Comment Jan 27, 2026 11:29am

Request Review

Copilot AI and others added 2 commits January 27, 2026 11:25
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
…bility

Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix prerendering error for header bar component Fix: useSidebar hook throws during SSR/prerendering Jan 27, 2026
Copilot AI requested a review from hotlong January 27, 2026 11:30
@hotlong hotlong marked this pull request as ready for review January 27, 2026 11:36
Copilot AI review requested due to automatic review settings January 27, 2026 11:36
@hotlong hotlong merged commit 8b1dea8 into copilot/fix-loading-issue-docs Jan 27, 2026
6 checks passed
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR fixes a Next.js build failure during static site generation where the header-bar component's SidebarTrigger calls useSidebar() without a SidebarProvider in the tree, causing a hard error. The solution modifies useSidebar() to return safe default values instead of throwing when the provider is missing.

Changes:

  • Modified useSidebar() hook to return DEFAULT_SIDEBAR_STATE when no provider exists, enabling graceful degradation during SSR/prerendering
  • Extracted DEFAULT_SIDEBAR_STATE constant with no-op functions for all sidebar operations
Comments suppressed due to low confidence (2)

packages/components/src/ui/sidebar.tsx:74

  • Silently returning default values when the provider is missing hides configuration errors from developers. This approach differs from the established pattern in the codebase where other context hooks (useCarousel, useChart, useFormField, useSchemaContext) throw errors when used outside their providers.

Consider adding a development-time warning to help developers identify misconfigurations:

function useSidebar() {
  const context = React.useContext(SidebarContext)
  if (!context) {
    if (process.env.NODE_ENV !== 'production') {
      console.warn(
        'useSidebar: No SidebarProvider found. Using default values. ' +
        'This may indicate a missing SidebarProvider in your component tree.'
      )
    }
    return DEFAULT_SIDEBAR_STATE
  }
  return context
}

This preserves SSR compatibility while alerting developers during development that they may be missing proper setup.

function useSidebar() {
  const context = React.useContext(SidebarContext)
  if (!context) {
    // Return default values to allow components to gracefully degrade without breaking the build
    return DEFAULT_SIDEBAR_STATE
  }

  return context
}

packages/components/src/ui/sidebar.tsx:74

  • The approach taken here differs from the ToggleGroupContext pattern (lines 16-21 in toggle-group.tsx) which provides a default value directly in createContext, preventing null checks altogether. Consider applying the same pattern here:
const SidebarContext = React.createContext<SidebarContextProps>(DEFAULT_SIDEBAR_STATE)

Then simplify useSidebar to:

function useSidebar() {
  return React.useContext(SidebarContext)
}

This approach:

  1. Eliminates the null check entirely
  2. Aligns with the ToggleGroupContext implementation pattern
  3. Still provides SSR compatibility
  4. Maintains graceful degradation

Note: You'd still want to add a dev warning (see other comment) to help developers identify when they're missing the provider.

const SidebarContext = React.createContext<SidebarContextProps | null>(null)

// Default sidebar state for when no provider exists (e.g., during SSR/prerendering)
const DEFAULT_SIDEBAR_STATE: SidebarContextProps = {
  state: "expanded",
  open: true,
  setOpen: () => {},
  openMobile: false,
  setOpenMobile: () => {},
  isMobile: false,
  toggleSidebar: () => {},
}

function useSidebar() {
  const context = React.useContext(SidebarContext)
  if (!context) {
    // Return default values to allow components to gracefully degrade without breaking the build
    return DEFAULT_SIDEBAR_STATE
  }

  return context
}

Comment on lines 66 to +70
function useSidebar() {
const context = React.useContext(SidebarContext)
if (!context) {
throw new Error("useSidebar must be used within a SidebarProvider.")
// Return default values to allow components to gracefully degrade without breaking the build
return DEFAULT_SIDEBAR_STATE
Copy link

Copilot AI Jan 27, 2026

Choose a reason for hiding this comment

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

The header-bar component (packages/components/src/renderers/navigation/header-bar.tsx:26) unconditionally renders a SidebarTrigger, but this creates an implicit coupling between header-bar and SidebarProvider. During SSR or when header-bar is used without a sidebar, the trigger renders but has no sidebar to control.

Consider one of these architectural improvements:

  1. Make the sidebar trigger optional in header-bar schema:
interface HeaderBarSchema {
  showSidebarTrigger?: boolean; // Default: false for better SSR compatibility
  // ... other props
}
  1. Add a dedicated slot for the trigger so users explicitly choose when to include it:
interface HeaderBarSchema {
  leftSlot?: SchemaNode[]; // Users can explicitly add SidebarTrigger here
  // ... other props
}

This would align with ObjectUI's principle of "JSON-driven composition" where components are explicitly configured rather than having implicit dependencies.

Copilot generated this review using guidance from repository custom instructions.

const SidebarContext = React.createContext<SidebarContextProps | null>(null)

// Default sidebar state for when no provider exists (e.g., during SSR/prerendering)
Copy link

Copilot AI Jan 27, 2026

Choose a reason for hiding this comment

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

The comment mentions "SSR/prerendering" but the actual issue is specifically about static site generation where components are rendered outside of a provider tree. Consider updating the comment to be more precise:

// Default sidebar state for graceful degradation when used outside SidebarProvider
// (e.g., during SSR, static generation, or standalone component usage)

This clarifies that it's not just an SSR concern but a broader architectural pattern for components that may be rendered in isolation.

Suggested change
// Default sidebar state for when no provider exists (e.g., during SSR/prerendering)
// Default sidebar state for graceful degradation when used outside SidebarProvider
// (e.g., during SSR, static generation, or standalone component usage)

Copilot uses AI. Check for mistakes.
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.

2 participants