> ## 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.

# KPdfLoadState: observe KPDF document loading progress

> KPdfLoadState tracks every stage of PDF loading — idle, decoding, ready with page count, or error — so you can show progress indicators and handle failures.

`KPdfLoadState` is the observable load lifecycle for a single KPDF viewer instance. Collect it from `KPdfViewerState.loadState` (a `StateFlow`) to drive loading indicators, show page counts, surface error messages, and gate actions that require a fully decoded document. The state machine progresses linearly from `Idle` → `Loading` → `Ready` on success, or `Idle` → `Loading` → `Error` on failure. Transitioning the viewer to a new source resets the state back to `Idle`.

## Variants

<ResponseField name="Idle" type="data object">
  No document is loaded and no load is in progress. This is the initial state of every viewer instance before `open()` is called, and the state the viewer returns to after `close()`.
</ResponseField>

<ResponseField name="Loading" type="data object">
  The SDK is actively fetching (for URL sources) or decoding the PDF bytes. Long-running network requests remain in `Loading` for their entire duration. Display a progress indicator while in this state.
</ResponseField>

<ResponseField name="Ready" type="data class">
  The document has been fully decoded and the first page is ready to render.

  <ResponseField name="pageCount" type="Int" required>
    Total number of pages in the document. Always `≥ 1` when `Ready` is emitted.
  </ResponseField>

  <ResponseField name="title" type="String?" required>
    The document title extracted from PDF metadata, or `null` if no title is present in the file.
  </ResponseField>
</ResponseField>

<ResponseField name="Error" type="data class">
  Document loading failed. Inspect `reason` to determine the failure type and decide whether to surface a retry action or a specific error message.

  <ResponseField name="reason" type="KPdfError" required>
    A sealed `KPdfError` value describing the failure. See [KPdfError variants](#kpdferror-variants) below.
  </ResponseField>
</ResponseField>

## KPdfError variants

`KPdfError` is a sealed interface with a `message: String` property on every variant. The following concrete types are available:

| Variant                                           | Description                                                                      |
| ------------------------------------------------- | -------------------------------------------------------------------------------- |
| `FileNotFound(path: String?)`                     | The local file could not be located at the given path.                           |
| `NetworkError(statusCode: Int?, reason: String?)` | A network request failed, optionally with an HTTP status code and reason phrase. |
| `Unauthorized`                                    | The request was rejected with a 401-equivalent response.                         |
| `NotFound`                                        | The remote resource returned a 404-equivalent response.                          |
| `CorruptedDocument`                               | The bytes were retrieved but could not be parsed as a valid PDF.                 |
| `Unknown(message: String)`                        | An unexpected error occurred; `message` contains the detail.                     |

## Collecting load state in Compose

Call `collectAsState()` on `KPdfViewerState.loadState` inside your composable, then branch on each variant with a `when` expression.

```kotlin theme={null}
@Composable
fun PdfLoadStatus(viewerState: KPdfViewerState) {
    val loadState by viewerState.loadState.collectAsState()

    when (val state = loadState) {
        KPdfLoadState.Idle -> {
            // Nothing to show yet
        }

        KPdfLoadState.Loading -> {
            CircularProgressIndicator()
        }

        is KPdfLoadState.Ready -> {
            Text("Document ready — ${state.pageCount} pages")
            state.title?.let { Text("Title: $it") }
        }

        is KPdfLoadState.Error -> {
            Text("Failed to load: ${state.reason.message}")
            Button(onClick = { viewerState.retry() }) {
                Text("Retry")
            }
        }
    }
}
```

`pageCount` is only available on the `Ready` variant. Guard any page-count logic with a smart cast or `(loadState as? KPdfLoadState.Ready)?.pageCount` to avoid a null or default value while the document is still loading.

## Notes

* `KPdfViewerState.loadState` is a `StateFlow<KPdfLoadState>`, so it always has a current value and never suspends on the first collection.
* Calling `viewerState.open(newSource)` while in `Ready` or `Error` resets `loadState` to `Idle` before beginning the next load cycle.
* If you only need `pageCount` for toolbar display, `KPdfViewerToolbar` reads it internally — you do not need to observe `loadState` yourself in that case.
