---
title: "JavaScript PDF viewer with zoom and pan | Nutrient SDK"
canonical_url: "https://www.nutrient.io/guides/web/viewer/zooming/"
md_url: "https://www.nutrient.io/guides/web/viewer/zooming.md"
last_updated: "2026-05-21T13:28:30.125Z"
description: "Configure zoom in your JavaScript PDF viewer with UI controls, API methods, and custom settings. Includes keyboard shortcuts and annotation handling."
---

# Zoom options in our JavaScript PDF viewer

Nutrient Web SDK enables document zooming through toolbar buttons, keyboard shortcuts, and programmatic API methods. Configure zoom behavior, scroll wheel interactions, and automatic zoom modes to create the optimal viewing experience.

## Zooming with the UI

Documents opened in Nutrient Web SDK’s viewer can be zoomed in on and out of using the corresponding toolbar buttons, `zoom-in` and `zoom-out`:

Zooming can also be controlled using keyboard shortcuts:

- Control/Command + + — Zoom in

- Control/Command + - — Zoom out

- Control/Command + 0 — Zoom to auto

- Control + Scroll wheel — Zoom in or out at mouse position

The `zoom-mode` button can be used to toggle the current zoom so that the page fits either the viewport width or the viewport height.

The `marquee-zoom` button, hidden by default, can be used to zoom to the area of a rectangle drawn by the user.

The `marquee-zoom` button is enabled in the [`NutrientViewer.Configuration`](https://www.nutrient.io/api/web/NutrientViewer.Configuration.html) object passed to [`NutrientViewer.load()`](https://www.nutrient.io/api/web/NutrientViewer.html#.load):

```js

NutrientViewer.load({
  // Add the `marquee-zoom` button to default toolbar items.
  toolbarItems: NutrientViewer.defaultToolbarItems.concat([
    { type: "marquee-zoom" }
  ])
}).then((instance) => {
    console.log("Viewer loaded with marquee zoom enabled");
  }).catch((error) => {
    console.error("Failed to load viewer:", error.message);
  });

```

Or, it can be enabled using the [`instance.setToolbarItems()`](https://www.nutrient.io/api/web/NutrientViewer.Instance.html#setToolbarItems) API method:

```js

// Add the `marquee-zoom` button after initialization.
instance.setToolbarItems((items) =>
  items.concat([{ type: "marquee-zoom" }])
);

```

## Zooming with the API

### Configuring zoom behavior

Control the zoom configuration granularly using the [`ZoomConfiguration`](https://www.nutrient.io/api/web/NutrientViewer.html#.ZoomConfiguration) object.

The zoom setting can be passed to [`NutrientViewer.Configuration#initialViewState`](https://www.nutrient.io/api/web/NutrientViewer.Configuration.html#initialViewState) when loading the viewer:

```js

NutrientViewer.load({
  initialViewState: new NutrientViewer.ViewState({
    // Configure zoom behavior with the `ZoomConfiguration` object.
    zoom: {
      // Set the zoom mode or numeric value.
      zoomMode: NutrientViewer.ZoomMode.FIT_TO_WIDTH,

      // Configure scroll wheel zoom behavior.
      wheelZoomMode: NutrientViewer.WheelZoomMode.ALWAYS,

      // Configure zoom options.
      options: {
        enableKeyboardZoom: true,
        enableGestureZoom: true
      }
    }
  })
}).then((instance) => {
    console.log("Viewer loaded with custom zoom configuration");
  }).catch((error) => {
    console.error("Failed to load viewer:", error.message);
  });

```

This can also be changed after initialization using `setViewState`:

```js

// Update the zoom configuration after initialization.
instance.setViewState(new NutrientViewer.ViewState({
  zoom: {
    // Set the zoom mode or numeric value.
    zoomMode: NutrientViewer.ZoomMode.FIT_TO_WIDTH,

    // Configure scroll wheel zoom behavior.
    wheelZoomMode: NutrientViewer.WheelZoomMode.ALWAYS,

    // Configure zoom options.
    options: {
      enableKeyboardZoom: true,
      enableGestureZoom: true
    }
  }
}));

```

To ensure backward compatibility, the `zoom` property of the [`viewState`](https://www.nutrient.io/api/web/NutrientViewer.ViewState.html#zoom) accepts a [`ZoomConfiguration`](https://www.nutrient.io/api/web/NutrientViewer.html#.ZoomConfiguration), or a [`ZoomMode`](https://www.nutrient.io/api/web/enums/NutrientViewer.ZoomMode.html), or a number:

```js

// Pass a `zoomMode` to zoom.

NutrientViewer.load({
  initialViewState: new NutrientViewer.ViewState({
    zoom: NutrientViewer.ZoomMode.FIT_TO_WIDTH
  })
}).then((instance) => {
    console.log("Viewer loaded with fit-to-width zoom");
  }).catch((error) => {
    console.error("Failed to load viewer:", error.message);
  });

```

```js

// Pass a number to zoom.

NutrientViewer.load({
  initialViewState: new NutrientViewer.ViewState({
    zoom: 7
  })
}).then((instance) => {
    console.log("Viewer loaded with 7x zoom");
  }).catch((error) => {
    console.error("Failed to load viewer:", error.message);
  });

```

### Available zoom modes

The following zoom modes are available through [`NutrientViewer.ZoomMode`](https://www.nutrient.io/api/web/enums/NutrientViewer.ZoomMode.html):

- `AUTO` aligns the page for the best viewing experience.

- `FIT_TO_WIDTH` fits the width of the broadest page into the viewport. The height might overflow.

- `FIT_TO_VIEWPORT` fits the current page into the viewport completely.

```js

instance.setViewState(new NutrientViewer.ViewState({
  zoom: {
    // Set the zoom mode.
    zoomMode: NutrientViewer.ZoomMode.FIT_TO_WIDTH
    // Other zoom configurations.
  }
}));

```

You can also specify a numeric zoom value instead of a mode:

```js

NutrientViewer.load({
  initialViewState: new NutrientViewer.ViewState({
    zoom: {
      // Set the zoom to a numeric value.
      zoomMode: 7
      // Other zoom configurations.
    }
  })
}).then((instance) => {
    console.log("Viewer loaded with numeric zoom value");
  }).catch((error) => {
    console.error("Failed to load viewer:", error.message);
  });

```

### Zooming at mouse position with the scroll wheel

Nutrient Web SDK offers three modes for scroll wheel zoom behavior, defined in [`WheelZoomMode`](https://www.nutrient.io/api/web/enums/NutrientViewer.WheelZoomMode.html):

- `WITH_CTRL` (default) — Zoom when Control + scroll wheel is used.

- `ALWAYS` — Always zoom on scroll wheel without requiring the Control key to be pressed.

- `DISABLED` — Completely disable scroll wheel zooming regardless of which key is pressed.

Configure this behavior when loading the viewer:

```js

NutrientViewer.load({
  //...
  initialViewState: new NutrientViewer.ViewState({
    zoom: {
      wheelZoomMode: NutrientViewer.WheelZoomMode.WITH_CTRL,
      // Other zoom configurations.
    },
  })
}).then((instance) => {
    console.log("Viewer loaded with Ctrl+wheel zoom enabled");
  }).catch((error) => {
    console.error("Failed to load viewer:", error.message);
  });

```

Or, change it after initialization:

```js

instance.setViewState(new NutrientViewer.ViewState({
  zoom: {
    wheelZoomMode: NutrientViewer.WheelZoomMode.WITH_CTRL
    // Other zoom configurations.
  }
}));

```

> This change deprecates `NutrientViewer.ViewState#enableAlwaysScrollToZoom`.

### Zoom options

- `enableKeyboardZoom` — Enables zooming via keyboard shortcuts (Control/Command + [+-]). Defaults to `true`.

- `enableGestureZoom` — Enable zooming via touch gestures. Defaults to `true`.

```js

NutrientViewer.load({
  initialViewState: new NutrientViewer.ViewState({
    zoom: {
      // Other zoom configurations.

      // Configure zoom options.
      options: {
        enableKeyboardZoom: false,
        enableGestureZoom: false
      }
    }
  })
}).then((instance) => {
    console.log("Viewer loaded with keyboard and gesture zoom disabled");
  }).catch((error) => {
    console.error("Failed to load viewer:", error.message);
  });

```

### Changing zoom scale increments

By default, each click on the zoom toolbar buttons increases or decreases the zooming scale by increments of 25 percent. To change this default zoom step, change the `zoomStep` property of the `viewState` object. Use a number greater than `1`.

The example below changes the zoom step to 10 percent:

```js

instance.setViewState((viewState) => viewState.set("zoomStep", 1.1));

```

### Querying current zoom values

The current zoom value can be queried with [`instance.currentZoomLevel`](https://www.nutrient.io/api/web/NutrientViewer.Instance.html#currentZoomLevel) at any time.

Other dynamic values related to zooming available in the current instance are:

- [`instance.minimumZoomLevel`](https://www.nutrient.io/api/web/NutrientViewer.Instance.html#minimumZoomLevel) — Minimum zoom level attainable using the UI or the API.

- [`instance.maximumZoomLevel`](https://www.nutrient.io/api/web/NutrientViewer.Instance.html#maximumZoomLevel) — Maximum zoom level attainable using the UI or the API.

### API zooming helpers

The API provides some helpers to make programmatic zoom handling easier.

This example zooms in to the document by a single step via [`NutrientViewer.ViewState#zoomIn()`](https://www.nutrient.io/api/web/NutrientViewer.ViewState.html#zoomIn):

```js

instance.setViewState((viewState) => viewState.zoomIn());

```

It has its counterpart, [`NutrientViewer.ViewState#zoomOut()`](https://www.nutrient.io/api/web/NutrientViewer.ViewState.html#zoomOut):

```js

instance.setViewState((viewState) => viewState.zoomOut());

```

Finally, [`instance.jumpAndZoomToRect()`](https://www.nutrient.io/api/web/NutrientViewer.Instance.html#jumpAndZoomToRect) can zoom to any part of the document.

This example navigates to page 10 of the document and zooms in to the bounding box of an annotation, making it take the entire viewport size:

```js

instance.jumpAndZoomToRect(10, annotation.boundingBox);

```

When the zoom value changes, Nutrient may rerender the page background to maintain image sharpness.

## Preventing zooming for annotations

By default, each annotation’s appearance scales to match the page zoom. To change this behavior, the `noZoom` flag can be set to `true` to prevent an annotation from being magnified when zooming in. This is currently only enabled for [`StampAnnotation`](https://www.nutrient.io/api/web/NutrientViewer.Annotations.StampAnnotation.html) and [`TextAnnotation`](https://www.nutrient.io/api/web/NutrientViewer.Annotations.TextAnnotation.html), with the exception of `TextAnnotation`s with the [`callout`](https://www.nutrient.io/api/web/NutrientViewer.Annotations.TextAnnotation.html#callout) property set.

The example below creates a [`TextAnnotation`](https://www.nutrient.io/api/web/NutrientViewer.Annotations.TextAnnotation.html) with the `noZoom` flag set to `true`:

```js

await instance.create([
  new NutrientViewer.Annotations.TextAnnotation({
    pageIndex: 0,
    boundingBox: new NutrientViewer.Geometry.Rect({
      left: 50,
      top: 150,
      width: 180,
      height: 25
    }),
    text: {
      format: "plain",
      value: "Text with noZoom flag"
    },
    noZoom: true
  })
]);

```
---

## Related pages

- [Client authentication and session renewal](/guides/web/viewer/client-authentication.md)
- [Create custom annotation toggle button](/guides/web/viewer/custom-annotation-toggle.md)
- [Embed Web SDK in a dashboard/app shell](/guides/web/viewer/embed-in-dashboard-app-shell.md)
- [JavaScript image viewer library](/guides/web/viewer/images.md)
- [JavaScript PDF viewer library](/guides/web/viewer.md)
- [Enhance PDF viewing with linearized downloading](/guides/web/viewer/linearized-downloads.md)
- [Mobile responsive JavaScript PDF viewer](/guides/web/viewer/mobile-responsive.md)
- [Office document viewing in JavaScript](/guides/web/viewer/office-documents.md)
- [Page layout and scroll options in our JavaScript PDF viewer](/guides/web/customizing-the-interface/document-presentation-options.md)
- [JavaScript PDF viewer library](/guides/web/viewer/pdf.md)
- [PDF document streaming in JavaScript](/guides/web/viewer/streaming.md)
- [Enable or disable permissions in our JavaScript viewer](/guides/web/features/document-permissions.md)
- [JavaScript Support in our PDF viewer](/guides/web/features/javascript.md)
- [macOS/Linux](/guides/web/viewer/troubleshooting.md)

