useVisualViewport
React hook to track Visual Viewport changes.
Returns the actual visible area in mobile WebView, which changes when the keyboard appears or the user zooms/scrolls.
Interface
function useVisualViewport(): { viewport: VisualViewportState | null };Parameters
This hook takes no parameters.
Return Value
- viewportVisualViewportState | null
Visual Viewport state object, or
nullif not supported (SSR or browser without Visual Viewport API).- viewport.widthnumber
Viewport width in pixels
- viewport.heightnumber
Viewport height in pixels
- viewport.offsetLeftnumber
Viewport left offset (px) from the layout viewport. Typically 0 unless horizontal scrolling or panning occurs
- viewport.offsetTopnumber
Viewport top offset (px) from the layout viewport. On iOS: Becomes negative when keyboard appears (e.g., -300px means 300px keyboard height). On Android: Typically remains 0. Use
-offsetTopto get accurate keyboard height on iOS - viewport.scalenumber
Pinch-zoom scaling factor. 1.0 = no zoom (default), > 1.0 = zoomed in, < 1.0 = zoomed out (rare, depends on viewport settings)
- viewport.widthnumber
Example
function CustomLayout() {
const { viewport } = useVisualViewport();
// Always check for null first
if (!viewport) {
return <div>Visual Viewport not supported</div>;
}
const { width, height, offsetTop, scale } = viewport;
// Hide floating UI when user zooms in
const showFloatingUI = scale <= 1.3;
return (
<div style={{ height }}>
{showFloatingUI && <FloatingButton />}
Viewport-aware content
</div>
);
}Detecting Zoom
const { viewport } = useVisualViewport();
if (viewport && viewport.scale > 1.3) {
// Hide floating UI when user zooms in
setShowFloatingButton(false);
}Notes
- SSR Safety:
viewportisnullon SSR or in browsers that don't support Visual Viewport API. Always check for null before accessing viewport properties. - Browser Support: Visual Viewport API is supported in modern mobile browsers. For unsupported environments, the hook returns
null. - Performance: Uses React's
startTransitionto prevent blocking updates during viewport changes. - Simpler Alternative: If you only need keyboard height, use
useKeyboardHeight()instead for a simpler API. - Platform Differences:
- iOS:
offsetTopbecomes negative when keyboard appears - Android:
offsetToptypically remains 0
- iOS:
- Use Cases:
- Detecting keyboard appearance
- Responding to pinch-zoom gestures
- Creating viewport-aware layouts
- Hiding/showing UI elements based on zoom level