Vize

window-size

Track the window size reactively.

Package @vizejs/composable/window-size
Own the source vize lib pull composable:window-size
Runtime exports useWindowSize
Gzip budget 1536 B

Minimal setup

Use a Vue 3.5+ project with Vue SFC compilation configured (see Vite+ integration).

vp install @vizejs/composable

Import the entry directly. Call lifecycle-bound utilities inside <script setup> so cleanup follows the component scope; consult the runtime contract for this entry's SSR and hydration behavior.

import { useWindowSize } from "@vizejs/composable/window-size";

Try it

Lay out review cards using this viewport's real size

Read actual window dimensions and support without letting responsive changes overwrite the user's layout choice or draft.

Open the interactive example

What to observe: Resize the preview and compare the readonly width and height with its viewport. Automatic uses two columns from 640 CSS pixels; Single column keeps one at every width. Toggle Show layout measurements and edit the draft, then resize again: both choices remain. The measurement label always reports actual dimensions independently of the layout override.

useWindowSize() exposes readonly width, height, and isSupported refs. Default inner dimensions include scrollbars; includeScrollbar: false would use the document root's client dimensions, and type: outer would measure the outer browser window. This example uses the default real iframe window and no injected host. During SSR and the first hydrating render, dimensions are 0 by default and support is false; mounting attaches the actual window and reads its size. Resize and orientationchange then refresh it. initialWidth and initialHeight can supply a consistent application-chosen SSR fallback, not a detected browser size. The native select, checkbox, and draft own separate local state. Scope disposal removes passive listeners and the host watcher. The surrounding page and this iframe need not have the same dimensions.

Compare the initial and interacted states
Lay out review cards using this viewport's real size: initial state
Initial state
Lay out review cards using this viewport's real size: state after the verified interactions
After the verified interactions

Copy the example

Save this complete SFC in your Vue project. Its public imports and source are the same ones executed in the preview.

<script setup lang="ts">
import { computed, ref } from "vue";
import { useWindowSize } from "@vizejs/composable/window-size";

const { width, height, isSupported } = useWindowSize();
const layout = ref<"automatic" | "single">("automatic");
const columns = computed(() => (layout.value === "automatic" && width.value >= 640 ? 2 : 1));
const showMeasurements = ref(false);
const draft = ref("");
</script>

<template>
  <div class="composable-example">
    <label>
      Guide layout
      <select v-model="layout">
        <option value="automatic">Automatic</option>
        <option value="single">Single column</option>
      </select>
    </label>
    <div
      class="viewport-guides"
      :style="{ gridTemplateColumns: `repeat(${columns}, minmax(0, 1fr))` }"
    >
      <section aria-label="Compiler review card">
        <strong>Compiler</strong>
        <p>Inspect the generated render function.</p>
      </section>
      <section aria-label="Type check review card">
        <strong>Type checking</strong>
        <p>Review diagnostics against the same source.</p>
      </section>
    </div>
    <label class="measurement-choice">
      <input v-model="showMeasurements" type="checkbox" /> Show layout measurements
    </label>
    <p v-if="showMeasurements">
      Layout: {{ columns }} {{ columns === 1 ? "column" : "columns" }} · Choice: {{ layout }}
    </p>
    <label>
      Viewport review draft
      <input v-model="draft" type="text" placeholder="Local draft survives a resize" />
    </label>
    <output aria-live="polite">
      Viewport: {{ width }} × {{ height }} CSS pixels · Window support:
      {{ isSupported ? "available" : "unavailable" }}
    </output>
    <p>
      Resize this preview's viewport to update its readonly dimensions. Automatic uses two columns
      from 640 px; Single column remains your choice at any width. Resizing preserves the local
      draft and measurement visibility.
    </p>
    <p>
      Default inner dimensions include scrollbars and describe this iframe, not the parent page or
      the outer browser window. SSR starts at 0 × 0 with support unavailable; after mounting, the
      real window supplies its dimensions.
    </p>
  </div>
</template>

<style scoped>
.viewport-guides {
  display: grid;
  gap: 12px;

  & section {
    min-inline-size: 0;
    padding: 12px;
    border: 1px solid currentColor;
    border-radius: 8px;
  }
}
.measurement-choice {
  display: inline-flex;
  align-items: center;
  gap: 6px;

  & input {
    inline-size: auto;
  }
}
</style>

Runtime contract

Utility Category Stability SSR Hydration Cleanup Targets Host globals Uses
useWindowSize dom experimental deterministic-fallback stable reactive-scope web, desktop window tryOnScopeDispose

API

useWindowSize

Track the window size reactively. Server renders expose initialWidth/initialHeight (default 0), so the first client render matches; the real size is applied as soon as a window resolves (after mounting when called inside a component). Resize (and orientation) listeners are passive and removed with the owning reactive scope.

function useWindowSize(options: UseWindowSizeOptions = {}): WindowSizeControls

Types

WindowSizeHost

Window-like capability observed by useWindowSize.

Member Type Description
innerWidth number Viewport width including the vertical scrollbar.
innerHeight number Viewport height including the horizontal scrollbar.
outerWidth number Outer browser window width.
outerHeight number Outer browser window height.
document { readonly documentElement: { readonly clientWidth: number; readonly clientHeight: number }; } Document whose root element reports the scrollbar-free viewport.

UseWindowSizeOptions

Options for useWindowSize.

Member Type Description
initialWidth? number Width exposed during server rendering and before hydration.
initialHeight? number Height exposed during server rendering and before hydration.
includeScrollbar? boolean Include scrollbars in the inner dimensions. When false, the root element's clientWidth/clientHeight are reported instead.
type? WindowSizeKind Report inner (viewport) or outer (browser window) dimensions.
listenOrientation? boolean Also re-measure on orientationchange for engines that resize late.
host? MaybeRefOrGetter<WindowSizeHost | null | undefined> Reactive window capability for alternate runtimes and tests.

WindowSizeControls

Reactive size returned by useWindowSize.

Member Type Description
width Readonly<Ref<number>> Current width in CSS pixels.
height Readonly<Ref<number>> Current height in CSS pixels.
isSupported Readonly<Ref<boolean>> Whether a window capability is attached. false during server rendering.