useWindowSize


Custom hook that tracks the size of the window.

Usage

import { useWindowSize } from 'usehooks-ts'

export default function Component() {
  const { width = 0, height = 0 } = useWindowSize()

  return (
    <div>
      The current window dimensions are:{' '}
      <code>{JSON.stringify({ width, height })}</code>
    </div>
  )
}

API

useWindowSize(options): WindowSize

Custom hook that tracks the size of the window.

Parameters

NameTypeDescription
optionsUseWindowSizeOptions<false>The options for customizing the behavior of the hook (optional).

Returns

WindowSize

An object containing the width and height of the window.

useWindowSize(options?): WindowSize<number>

Custom hook that tracks the size of the window.

Parameters

NameTypeDescription
options?Partial<UseWindowSizeOptions<true>>The options for customizing the behavior of the hook (optional).

Returns

WindowSize<number>

An object containing the width and height of the window.

Type aliases

Ƭ UseWindowSizeOptions<InitializeWithValue>: Object

Hook options.

Type parameters

NameTypeDescription
InitializeWithValueextends boolean | undefinedIf true (default), the hook will initialize reading the window size. In SSR, you should set it to false, returning undefined initially.

Type declaration

NameTypeDescription
debounceDelay?numberThe delay in milliseconds before the state is updated (disabled by default for retro-compatibility). Default ts undefined
initializeWithValueInitializeWithValueIf true (default), the hook will initialize reading the window size. In SSR, you should set it to false, returning undefined initially. Default ts true

Ƭ WindowSize<T>: Object

Represent the dimension of the window.

Type parameters

NameTypeDescription
Textends number | undefined = number | undefinedThe type of the dimension (number or undefined).

Type declaration

NameTypeDescription
heightTThe height of the window.
widthTThe width of the window.

Hook

import { useState } from 'react'

import {
  useDebounceCallback,
  useEventListener,
  useIsomorphicLayoutEffect,
} from 'usehooks-ts'

type WindowSize<T extends number | undefined = number | undefined> = {
  width: T
  height: T
}

type UseWindowSizeOptions<InitializeWithValue extends boolean | undefined> = {
  initializeWithValue: InitializeWithValue
  debounceDelay?: number
}

const IS_SERVER = typeof window === 'undefined'

// SSR version of useWindowSize.
export function useWindowSize(options: UseWindowSizeOptions<false>): WindowSize
// CSR version of useWindowSize.
export function useWindowSize(
  options?: Partial<UseWindowSizeOptions<true>>,
): WindowSize<number>
export function useWindowSize(
  options: Partial<UseWindowSizeOptions<boolean>> = {},
): WindowSize | WindowSize<number> {
  let { initializeWithValue = true } = options
  if (IS_SERVER) {
    initializeWithValue = false
  }

  const [windowSize, setWindowSize] = useState<WindowSize>(() => {
    if (initializeWithValue) {
      return {
        width: window.innerWidth,
        height: window.innerHeight,
      }
    }
    return {
      width: undefined,
      height: undefined,
    }
  })

  const debouncedSetWindowSize = useDebounceCallback(
    setWindowSize,
    options.debounceDelay,
  )

  function handleSize() {
    const setSize = options.debounceDelay
      ? debouncedSetWindowSize
      : setWindowSize

    setSize({
      width: window.innerWidth,
      height: window.innerHeight,
    })
  }

  useEventListener('resize', handleSize)

  // Set size at the first client-side load
  useIsomorphicLayoutEffect(() => {
    handleSize()
  }, [])

  return windowSize
}