Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Sep 6, 2025

The BOffcanvas component with the responsive prop was causing hydration mismatch errors in SSR environments due to inconsistent initial state between server and client rendering.

Problem

When using BOffcanvas with the responsive prop in SSR applications (Nuxt, Next.js, etc.), the component would evaluate breakpoints differently during SSR vs client hydration:

  • SSR Phase: No window object exists, so useBreakpoints returns fallback values
  • Client Hydration: Real window dimensions are available, causing different breakpoint evaluation
  • Result: isOpenByBreakpoint would have different initial values, triggering hydration mismatch errors
<!-- This would cause hydration issues in SSR -->
<BOffcanvas v-model="show" responsive="md" title="My Offcanvas">
  Content here
</BOffcanvas>

Users had to work around this by wrapping the component in client-only components, which defeats the purpose of SSR.

Solution

The fix ensures SSR compatibility by initializing isOpenByBreakpoint with an SSR-safe default value (false) and deferring the actual breakpoint evaluation to the onMounted hook (client-side only):

- const isOpenByBreakpoint = ref(props.responsive !== undefined && !smallerOrEqualToBreakpoint.value)
+ // Initialize with SSR-safe default value to prevent hydration mismatches
+ // The actual breakpoint evaluation is deferred to onMounted (client-side only)
+ const isOpenByBreakpoint = ref(false)

 onMounted(() => {
-  if (props.responsive !== undefined)
+  if (props.responsive !== undefined) {
+    // Update the breakpoint state after mounting (client-side only)
+    isOpenByBreakpoint.value = !smallerOrEqualToBreakpoint.value
     emit('breakpoint', buildTriggerableEvent('breakpoint'), isOpenByBreakpoint.value)
+  }
 })

Benefits

  • ✅ Eliminates hydration mismatch errors in SSR environments
  • ✅ No more need for client-only wrappers around responsive BOffcanvas
  • ✅ Maintains all existing functionality and responsive behavior
  • ✅ No breaking changes to props, events, or exposed methods
  • ✅ No performance impact - same runtime behavior once mounted

The component now works seamlessly in SSR environments while preserving all responsive functionality after the initial client-side mount.

Fixes #1982.


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

@bolt-new-by-stackblitz
Copy link

Review PR in StackBlitz Codeflow Run & review this pull request in StackBlitz Codeflow.

Copilot AI changed the title [WIP] BOffcanvas responsive SSR compatibility fix: BOffcanvas responsive SSR compatibility - defer breakpoint evaluation to client-side Sep 6, 2025
Copilot AI requested a review from VividLemon September 6, 2025 01:49
Copy link
Member

@VividLemon VividLemon left a comment

Choose a reason for hiding this comment

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

Tested locally, no hydration issue with either in responsive or outside responsive breakpoint

@VividLemon VividLemon marked this pull request as ready for review September 9, 2025 01:05
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 9, 2025

Important

Review skipped

Bot user detected.

To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.


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

@pkg-pr-new
Copy link

pkg-pr-new bot commented Sep 9, 2025

bsvn-vite-ts

npm i https://pkg.pr.new/bootstrap-vue-next/bootstrap-vue-next@2833
npm i https://pkg.pr.new/bootstrap-vue-next/bootstrap-vue-next/@bootstrap-vue-next/nuxt@2833

commit: 9b543c0

@pkg-pr-new
Copy link

pkg-pr-new bot commented Sep 9, 2025

bsvn-vite-ts

npm i https://pkg.pr.new/bootstrap-vue-next/bootstrap-vue-next@2833
npm i https://pkg.pr.new/bootstrap-vue-next/bootstrap-vue-next/@bootstrap-vue-next/nuxt@2833

commit: 9b543c0

@VividLemon VividLemon merged commit ab99819 into main Sep 9, 2025
8 checks passed
@github-actions github-actions bot mentioned this pull request Sep 9, 2025
xvaara added a commit to xvaara/bootstrap-vue-next that referenced this pull request Sep 11, 2025
* upstream/main: (32 commits)
  chore: release main (bootstrap-vue-next#2838)
  feat(BButtonToolbar): Add keyboard navigation support (bootstrap-vue-next#2837)
  fix(BFormSelect): modelValue not being applied during SSR (bootstrap-vue-next#2835)
  feat(BTable): Implement keyboard navigation (bootstrap-vue-next#2834)
  fix: BOffcanvas responsive SSR compatibility - defer breakpoint evaluation to client-side (bootstrap-vue-next#2833)
  chore: release main (bootstrap-vue-next#2831)
  fix(BDropdown): transition broken by inline display styles (bootstrap-vue-next#2832)
  feat: change useColorMode selector from 'body' to 'html' (bootstrap-vue-next#2830)
  chore: release main (bootstrap-vue-next#2817)
  feat: Add headerAttrs prop to BOffcanvas and BModal components
  docs: Add useScrollspy documentation
  fix: Remove lazy-modifier warning on FormInput docs (bootstrap-vue-next#2825)
  feat(BSort)!: Implement initial-sort-direction and move compare from sort-by to fields (bootstrap-vue-next#2777)
  docs(table): fix incorrect list item (bootstrap-vue-next#2823)
  docs: Fix grammar in documentation data files (bootstrap-vue-next#2816)
  doc(BTooltip): Parity pass (bootstrap-vue-next#2762)
  docs(BOverlay): Parity pass (bootstrap-vue-next#2767)
  feat: implement BFormRating disabled state (bootstrap-vue-next#2753) (bootstrap-vue-next#2793)
  docs: fix otp for index and reference pages (bootstrap-vue-next#2819)
  docs(BApp): add some additional details around legacy plugin use (bootstrap-vue-next#2820)
  ...
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.

BOffcanvas responsive SSR compatibility

2 participants