Responsive Rendering
Breakpoint-driven rendering: slot switching, show/hide, and a hydration-safe breakpoint composable.
| Package | @vizejs/ui/responsive |
| Maturity | stable |
| Own the source | vize lib pull responsive |
| Requires | — |
| Aliases | breakpoints, use breakpoint, show hide, media query rendering |
| Covers | Chakra Show/Hide, Vuetify useDisplay, VueUse useBreakpoints |
Minimal setup
Use a Vue 3.5+ project with Vue SFC compilation configured (see Vite+ integration).
vp install @vizejs/ui
Add the public import below to <script setup lang="ts">. Components provide behavior without styles; the preview uses optional Paper styles.
import { ResponsiveShow, ResponsiveSwitch } from "@vizejs/ui/responsive";
Or copy the source into your project with vize lib pull responsive (see Source Distribution).
Try it
This is the basic example maintained with the component source, using the public package imports. The preview adds the optional Paper styles.
Open the interactive example · Styling these components
Copy the example
<!-- Navigation that switches between a compact and a full layout by breakpoint, rendered from an SSR width. -->
<script setup lang="ts">
import { ResponsiveShow, ResponsiveSwitch } from "@vizejs/ui/responsive";
</script>
<template>
<header>
<ResponsiveSwitch as="nav" :ssr-width="1024" aria-label="Primary">
<template #base>
<a href="/menu">Menu</a>
</template>
<template #md>
<a href="/">Home</a>
<a href="/docs">Docs</a>
<a href="/blog">Blog</a>
</template>
</ResponsiveSwitch>
<ResponsiveShow above="lg" :ssr-width="1024">
<a href="/signup">Create account</a>
</ResponsiveShow>
</header>
</template>
API
ResponsiveShow
Source: src/families/layout/responsive/responsive-show.vue
Props
| Prop | Type | Default | Description |
|---|---|---|---|
above |
string |
undefined |
Show only when the viewport is at least this breakpoint wide. |
below |
string |
undefined |
Show only when the viewport is narrower than this breakpoint. |
breakpoints |
BreakpointMap |
defaultBreakpoints |
Named minimum widths in CSS pixels. |
ssrWidth |
number |
undefined |
Viewport width assumed during server rendering and hydration. Without it, range-limited content is hidden until mount. |
hideMode |
ResponsiveHideMode |
"unmount" |
"unmount" removes hidden content (the empty wrapper stays, hidden); "hidden" keeps it in the DOM under the hidden wrapper (state is preserved). |
Slots
| Slot | Slot props | Description |
|---|---|---|
default |
ResponsiveShowSlotState |
Content shown inside the breakpoint range. |
Exposed
| Member | Type | Description |
|---|---|---|
visible |
— | |
width |
— |
ResponsiveSwitch
Source: src/families/layout/responsive/responsive-switch.vue
Props
| Prop | Type | Default | Description |
|---|---|---|---|
as |
PrimitiveAs |
"div" |
Native element, custom element, or component to render. |
breakpoints |
BreakpointMap |
defaultBreakpoints |
Named minimum widths in CSS pixels. |
ssrWidth |
number |
undefined |
Viewport width assumed during server rendering and hydration. |
Slots
| Slot | Slot props | Description |
|---|---|---|
default |
ResponsiveSwitchSlotState |
Rendered when no breakpoint-named slot matches. Receives the active breakpoint. |
base |
ResponsiveSwitchSlotState |
Rendered below every breakpoint (before any breakpoint is reached). |
Exposed
| Member | Type | Description |
|---|---|---|
element |
Readonly<ShallowRef<HTMLElement | null>> |
Template ref to the rendered root element. |
active |
— | |
width |
— |
Behavior
Normative state x input -> outcome table for responsive-switch.vue,
responsive-show.vue, and useBreakpoint (@vizejs/ui/responsive). Rows are
proven by responsive.test.ts and responsive-ssr.test.ts; compile-only
assertions live in responsive.types.test-d.ts.
| # | State | Input | Outcome | Proven by |
|---|---|---|---|---|
| RS1 | breakpoint map | resolve width | the largest breakpoint whose minimum is reached wins; unknown width or below all resolves null |
resolves the largest reached breakpoint deterministically |
| RS2 | component setup | mount, then resize | width starts at ssrWidth, adopts the real viewport after mount, and follows resize until unmount |
useBreakpoint starts at ssrWidth, reads the real width after mount, and follows resize |
| RS3 | effect scope | custom map / immediate / no scope | custom names resolve, injected hosts are read immediately, and a missing scope throws VIZE_UI_RESPONSIVE_SETUP |
useBreakpoint accepts custom maps, immediate reads, injected hosts, and rejects missing scopes |
| RS4 | ResponsiveSwitch | viewport crosses breakpoints | the largest reached breakpoint slot renders, else base (above zero width), else default |
ResponsiveSwitch renders the largest reached breakpoint slot with fallbacks |
| RS5 | ResponsiveShow | outside above/below range |
content unmounts inside a hidden wrapper (unmount) or stays mounted under it (hidden); unknown breakpoint names hide |
ResponsiveShow unmounts or hides content outside its range |
| RS6 | SSR with ssrWidth |
isolated requests | byte-identical markup chosen from ssrWidth |
renders byte-identical breakpoint markup from ssrWidth across requests |
| RS7 | hydration | real width differs from SSR | hydrates without mismatch warnings, then switches to the real viewport | hydrates with the ssrWidth layout, then adopts the real viewport |
| RS8 | DOM/SSR/Vapor | compile | both SFCs compile in every renderer lane | scripts/check-renderers.ts |
ResponsiveShow uses display: contents, so its wrapper never affects layout.