Skip to content

Responsive Media ​

2.2.2 ​

2026-10-02

  • Changed: the shared responsiveState object, created once for the whole package, used to be created the moment any part of the package was loaded, so a bundler could not remove it. It is now created in a separate source file, and the package declares sideEffects: false in package.json. A bundler no longer keeps the shared state when only a part of the package is imported: useMediaQuery from responsive-media/vue fell from about 6.7 kB to 0.6 kB minified, and responsive-media/container from 7.7 kB to 6.8 kB. Behavior and public API are unchanged.
  • Added: npm run size in the package repository measures every entry point and typical imports. A test guards the tree-shaking result. See Reference.

2.2.1 ​

2026-10-02

  • Fixed: with deferred hydration, a component that hydrates later than the first tick after mounting — an async component, a lazily hydrated section — met the real state instead of the server's and mismatched. The Vue plugin now takes commit: 'manual': the server's values stay until commitHydration() is called, with commitTimeout (10 seconds by default) as a fallback, and defineResponsive() returns commitHydration next to plugin. The Nuxt module uses it: it commits when Nuxt reports app:suspense:resolve, that is, when the page has finished hydrating. The default for plain Vue stays 'auto', the next tick after mounting. See SSR & Hydration.

2.2.0 ​

2026-10-02

  • New: hydration without a mismatch. In Vue, defineResponsive() takes hydration: 'deferred': while the app mounts over server-rendered markup, the plugin keeps the server's values and applies the real ones on the next tick, so Vue reports no hydration mismatch. A client-only app is never deferred. In React the hooks now return the server snapshot (getSsrState()) as getServerSnapshot, so hydration no longer ends in a recoverable error when the browser's size differs from ssrState. See SSR & Hydration.
  • New: request hints for the server. resolveSsrState(config, input, options?) chooses the server state from a cookie (the browser's own <width>x<height>) and a user-agent (mobile, tablet or desktop), with detectDevice(), serializeViewportCookie(), parseViewportCookie(), statesFromSize() and getSsrState() as the pieces. In Vue the plugin takes the result as app.use(plugin, { ssrState }), and on the server it gives every app its own state, so concurrent requests no longer share one.
  • New: useMediaQuery() in Vue accepts a string, a ref or a getter, and re-subscribes when the query changes.
  • New: useResponsiveValue(map, fallback?) in Vue and React — the value of the first active breakpoint in map; typed by the config when it comes from defineResponsive().
  • New: useUserPreferences() in Vue and React — dark, light, reducedMotion, highContrast, lowContrast, noHover, coarsePointer, forcedColors and print over the accessibility preset, with nothing to configure; and getUserPreferencesState() for plain JavaScript.
  • New: useViewportSize(options?) in Vue and React, and getViewportSize() / subscribeViewportSize() in the core — the window size as numbers, throttled.
  • New: CSS from the same config — toMediaQueries(), toScssModule(), toScssMap(), toCustomMedia() and toTailwindScreens(). See CSS Integration.
  • New: responsive-media/testing — createViewportMock() replaces window.matchMedia with a controllable viewport (setViewport(), setFeature()), and evaluateMediaQuery() is the evaluator on its own. See Testing.
  • New in the Nuxt module: hydration (default 'deferred'), ssrHints ('cookie', 'user-agent'), ssrDevices, cookie, devBadge (a breakpoint badge in development) and css (scss, customMedia — generated stylesheet files). useResponsiveValue, useUserPreferences and useViewportSize are auto-imported too. The responsive key of nuxt.config.ts is now typed, so the editor completes and checks it. See Nuxt Integration.
  • Changed: the Nuxt module now defaults to hydration: 'deferred', so the first client render uses the server's values and the real ones arrive right after mounting. Set hydration: 'immediate' to keep the 2.1 behavior.
  • Fixed: React useResponsive() returned the real state as its server snapshot, which made hydration mismatch whenever the browser's size differed from the server's guess. It now returns the server snapshot.
  • Docs: Other Frameworks shows Svelte, Solid and Angular on the existing state object, which already follows the store contract.