> ## Documentation Index
> Fetch the complete documentation index at: https://mahmoud-b28887f9.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# KPdfViewerState: central controller for the PDF viewer

> KPdfViewerState is the state holder and controller for a KPDF viewer instance, exposing observable flows and methods for navigation, zoom, save, and export.

`KPdfViewerState` is the main interface you interact with after creating a viewer. It exposes the document's loading and rendering state through `StateFlow` properties, and provides methods to navigate pages, control zoom, open files from the device, save the document, hand it off to an external app, render individual pages off-screen, and release resources. One `KPdfViewerState` instance maps to one visible viewer; share the same instance across `KPdfViewer`, `KPdfThumbnailStrip`, and `KPdfViewerToolbar` so they stay in sync.

In Compose, obtain an instance through `rememberPdfViewerState`. For non-Compose contexts, use [`KPdfFactory`](/api/kpdf-factory).

## Observable properties

These properties expose the current state of the viewer. Collect them with `collectAsState()` in Compose or with `collect {}` in a coroutine scope outside Compose.

<ResponseField name="source" type="KPdfSource" required>
  The source that is currently loaded or being loaded. Updated synchronously when you call `open(source)`.
</ResponseField>

<ResponseField name="config" type="KPdfViewerConfig" required>
  The viewer configuration that was provided when this state was created. Immutable for the lifetime of the state instance.
</ResponseField>

<ResponseField name="loadState" type="StateFlow<KPdfLoadState>" required>
  Tracks the overall document loading lifecycle. Observe this to show loading indicators and handle errors.
</ResponseField>

<ResponseField name="currentPageIndex" type="StateFlow<Int>" required>
  The 0-based index of the page currently displayed in the viewer.
</ResponseField>

<ResponseField name="currentZoom" type="StateFlow<Float>" required>
  The active zoom level as a `Float`. The range is determined by the `minZoom` and `maxZoom` values in `KPdfViewerConfig`.
</ResponseField>

<ResponseField name="renderedPage" type="StateFlow<KPdfRenderedPageState>" required>
  The rendering state of the currently active page surface. Use this to react to render completion or render failures.
</ResponseField>

<ResponseField name="openDocumentState" type="StateFlow<KPdfOpenDocumentState>" required>
  Tracks the state of a device-picker open request initiated by `requestOpenFromDevice()`. Progresses through `Idle`, `AwaitingSelection`, `Success`, `Cancelled`, and `Error`. See [`KPdfOpenDocumentState`](/api/kpdf-open-document-state).
</ResponseField>

<ResponseField name="saveState" type="StateFlow<KPdfSaveState>" required>
  Tracks the state of a save request initiated by `requestSave()` or `savePdf()`. Progresses through `Idle`, `Exporting`, `AwaitingDestination`, `Success`, `Cancelled`, and `Error`. See [`KPdfSaveState`](/api/kpdf-save-state).
</ResponseField>

<ResponseField name="externalOpenState" type="StateFlow<KPdfExternalOpenState>" required>
  Tracks the state of an external-app open request initiated by `requestOpenInExternalApp()` or `openInExternalApp()`. Progresses through `Idle`, `Exporting`, `AwaitingExternalApp`, `Success`, `Cancelled`, and `Error`. See [`KPdfExternalOpenState`](/api/kpdf-external-open-state).
</ResponseField>

## Methods

### open

Opens a PDF source, cancelling any in-flight load or render work owned by this state instance.

<ParamField path="source" type="KPdfSource" default="this.source">
  The source to open. Defaults to the source already held by this state, which means calling `open()` with no arguments reloads the current document.
</ParamField>

```kotlin theme={null}
// Open a new remote document
viewerState.open(
    KPdfSource.Url("https://example.com/new-document.pdf")
)

// Reload the current source
viewerState.open()
```

### retry

Retries the most recent `open` request. Call this when `loadState` reports a failure and you want to give the user a way to try again without changing the source.

```kotlin theme={null}
Button(onClick = { viewerState.retry() }) {
    Text("Try again")
}
```

### nextPage

Advances the viewer to the next page. Has no effect when the last page is already displayed.

```kotlin theme={null}
Button(onClick = { viewerState.nextPage() }) {
    Text("Next")
}
```

### previousPage

Moves the viewer back to the immediately preceding page. Has no effect when the first page is already displayed.

```kotlin theme={null}
Button(onClick = { viewerState.previousPage() }) {
    Text("Previous")
}
```

### goToPage

Navigates directly to a specific page by its 0-based index.

<ParamField path="index" type="Int" required>
  The 0-based index of the target page. Page 1 of the document is index `0`.
</ParamField>

```kotlin theme={null}
// Jump to the eleventh page (index 10)
viewerState.goToPage(10)
```

### setZoom

Sets the zoom level for the active page surface to an exact value.

<ParamField path="zoom" type="Float" required>
  The target zoom level. Should be within the `minZoom`–`maxZoom` range defined in `KPdfViewerConfig`; values outside the range are coerced.
</ParamField>

```kotlin theme={null}
viewerState.setZoom(1.5f)
```

### zoomIn

Increases the current zoom by one viewer-defined step.

### zoomOut

Decreases the current zoom by one viewer-defined step.

### resetZoom

Resets the zoom back to the configured minimum zoom level.

```kotlin theme={null}
Button(onClick = { viewerState.zoomOut() }) { Text("Zoom out") }
Button(onClick = { viewerState.zoomIn() }) { Text("Zoom in") }
Button(onClick = { viewerState.resetZoom() }) { Text("Reset") }
```

### requestOpenFromDevice

Triggers the platform's native document picker so the user can select a PDF from local storage. When the user completes the picker flow, `openDocumentState` transitions to `Success` with the selected source. Call `open(selectedSource)` to load it.

<ParamField path="mimeTypes" type="List<String>" default="listOf(&#x22;application/pdf&#x22;)">
  The MIME types accepted by the platform picker. Defaults to PDF only.
</ParamField>

```kotlin theme={null}
// Trigger the picker
Button(onClick = { viewerState.requestOpenFromDevice() }) {
    Text("Open local PDF")
}

// React to the result
val openState by viewerState.openDocumentState.collectAsState()
LaunchedEffect(openState) {
    val selected = (openState as? KPdfOpenDocumentState.Success)?.source
        ?: return@LaunchedEffect
    viewerState.open(selected)
}
```

### requestSave

Requests that the SDK export the current PDF and trigger the platform's save/destination picker. Observe `saveState` to react to the outcome.

<ParamField path="suggestedFileName" type="String?" default="null">
  The file name pre-filled in the platform save dialog. Pass `null` to let the platform decide.
</ParamField>

<ParamField path="mimeType" type="String" default="KPdfSaveRequest.DefaultMimeType">
  The MIME type used when writing the file. Defaults to `application/pdf`.
</ParamField>

```kotlin theme={null}
Button(onClick = { viewerState.requestSave(suggestedFileName = "report.pdf") }) {
    Text("Save")
}

val saveState by viewerState.saveState.collectAsState()
when (saveState) {
    KPdfSaveState.Idle            -> Unit
    KPdfSaveState.Exporting       -> Text("Preparing PDF...")
    is KPdfSaveState.AwaitingDestination -> Text("Choose where to save.")
    is KPdfSaveState.Success      -> Text("Saved.")
    is KPdfSaveState.Cancelled    -> Text("Save cancelled.")
    is KPdfSaveState.Error        -> Text("Save failed.")
}
```

### savePdf

Alias for `requestSave`. Accepts the same parameters and delegates directly to it. Prefer whichever name reads more clearly at your call site.

<ParamField path="suggestedFileName" type="String?" default="null">
  The file name pre-filled in the platform save dialog.
</ParamField>

<ParamField path="mimeType" type="String" default="KPdfSaveRequest.DefaultMimeType">
  The MIME type used when writing the file.
</ParamField>

### requestOpenInExternalApp

Requests that the SDK export the current PDF and hand it to an installed app that can open PDF content (e.g., a system PDF viewer). Observe `externalOpenState` to react to the outcome.

<ParamField path="suggestedFileName" type="String?" default="null">
  The file name suggested to the receiving app or OS share sheet.
</ParamField>

<ParamField path="mimeType" type="String" default="KPdfExternalOpenRequest.DefaultMimeType">
  The MIME type used when handing off the file. Defaults to `application/pdf`.
</ParamField>

### openInExternalApp

Alias for `requestOpenInExternalApp`. Accepts the same parameters and delegates directly to it.

<ParamField path="suggestedFileName" type="String?" default="null">
  The file name suggested to the receiving app or OS share sheet.
</ParamField>

<ParamField path="mimeType" type="String" default="KPdfExternalOpenRequest.DefaultMimeType">
  The MIME type used when handing off the file.
</ParamField>

```kotlin theme={null}
// Open with the suggested file name
viewerState.openInExternalApp(suggestedFileName = "invoice.pdf")

// Observe the result
val externalState by viewerState.externalOpenState.collectAsState()
when (externalState) {
    KPdfExternalOpenState.Idle               -> Unit
    KPdfExternalOpenState.Exporting          -> Text("Preparing PDF...")
    is KPdfExternalOpenState.AwaitingExternalApp -> Text("Opening external app...")
    is KPdfExternalOpenState.Success         -> Text("Opened.")
    is KPdfExternalOpenState.Cancelled       -> Text("Cancelled.")
    is KPdfExternalOpenState.Error           -> Text("Unable to open.")
}
```

### renderPage

Renders a specific page to an off-screen bitmap. This is a `suspend` function; call it from a coroutine scope. Use it when you need pixel-level access to a page — for example, to feed a custom sharing flow — rather than to display it in the viewer.

<ParamField path="pageIndex" type="Int" required>
  The 0-based index of the page to render.
</ParamField>

<ParamField path="targetWidth" type="Int" required>
  The desired width of the output bitmap in pixels.
</ParamField>

<ParamField path="targetHeight" type="Int" required>
  The desired height of the output bitmap in pixels.
</ParamField>

<ParamField path="zoom" type="Float" default="1f">
  The zoom factor to apply when rendering. Defaults to `1f` (no zoom).
</ParamField>

Returns `Result<KPdfPageBitmap>`. Check `isSuccess` before using the value.

```kotlin theme={null}
scope.launch {
    viewerState.renderPage(
        pageIndex = 0,
        targetWidth = 1080,
        targetHeight = 1920,
        zoom = 2f,
    ).onSuccess { bitmap ->
        // Use bitmap.image for your platform-specific rendering
    }.onFailure { error ->
        println("Render failed: ${error.message}")
    }
}
```

### exportPdf

Exports the currently configured PDF source as raw bytes. This is a `suspend` function. Use the returned bytes to implement a custom share flow that bypasses the SDK's built-in save/external-open paths.

Returns `Result<ByteArray>`.

```kotlin theme={null}
scope.launch {
    viewerState.exportPdf().fold(
        onSuccess = { bytes -> sharePdfBytes(bytes) },
        onFailure = { error -> println(error.message) },
    )
}
```

### close

Closes the active document and releases all resources owned by this state instance, including cached pages and coroutine work. Call this when the viewer is being torn down outside of Compose lifecycle management.

```kotlin theme={null}
override fun onDestroy() {
    super.onDestroy()
    viewerState.close()
}
```
