Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mahmoud-b28887f9.mintlify.app/llms.txt

Use this file to discover all available pages before exploring further.

KPdfSource is the sealed interface that tells KPDF where to find a PDF document. Every viewer instance is backed by exactly one source, and the SDK treats distinct source values as distinct documents. Choose the variant that matches how your app obtains the PDF — a remote URL, an already-decoded byte array, or an inline Base64 string — and pass it to rememberPdfViewerState or KPdfViewerState.open.

The three source variants

Use KPdfSource.Url when the document lives at a network address. Pass custom headers to authenticate the request or negotiate the response format. KPDF treats headers as part of the source identity: two Url instances with the same URL but different headers are considered different sources, so the viewer reloads when headers change.
// Public document — no headers needed
val publicSource = KPdfSource.Url(
    url = "https://example.com/report.pdf"
)

// Protected document — pass a Bearer token
val authSource = KPdfSource.Url(
    url = "https://api.example.com/documents/42.pdf",
    headers = mapOf("Authorization" to "Bearer eyJhbGci...")
)

// Multiple custom headers
val negotiatedSource = KPdfSource.Url(
    url = "https://api.example.com/export",
    headers = mapOf(
        "Authorization" to "Bearer eyJhbGci...",
        "X-Tenant-Id"   to "acme-corp",
        "Accept"        to "application/pdf",
    )
)
Use KPdfSource.Bytes when your app already has the PDF content in memory — for example, after downloading it yourself, generating it programmatically, or reading it from a local file. Hand the ByteArray directly to KPDF; the SDK does not perform any network requests.
// From your own network call
val pdfBytes: ByteArray = myHttpClient.get("https://example.com/file.pdf")
val bytesSource = KPdfSource.Bytes(data = pdfBytes)

// From a local file read
val fileBytes: ByteArray = File("/path/to/document.pdf").readBytes()
val fileSource = KPdfSource.Bytes(data = fileBytes)
KPdfSource.Bytes implements equals and hashCode using contentEquals / contentHashCode on the underlying array, so two Bytes instances wrapping identical content compare as equal.
Use KPdfSource.Base64 when the PDF arrives as a Base64-encoded string, such as from a JSON API response or an embedded asset. Pass either a raw Base64 string or a complete data URL — KPDF handles both formats.
// Raw Base64 string
val rawBase64Source = KPdfSource.Base64(
    value = "JVBERi0xLjQKJcOkw7zDtsOfCjIgMCBv..."
)

// Data URL (data:application/pdf;base64,...)
val dataUrlSource = KPdfSource.Base64(
    value = "data:application/pdf;base64,JVBERi0xLjQKJcOkw7zDtsOfCjIgMCBv..."
)

Passing a source to the viewer

@Composable
fun PdfScreen() {
    val source = remember {
        KPdfSource.Url(
            url = "https://example.com/annual-report.pdf",
            headers = mapOf("Authorization" to "Bearer eyJhbGci...")
        )
    }

    val viewerState = rememberPdfViewerState(source = source)

    KPdfViewer(
        state = viewerState,
        modifier = Modifier.fillMaxSize(),
    )
}
To switch the active document at runtime, call viewerState.open(newSource). KPDF cancels any in-flight work and starts loading the new source immediately.
Button(onClick = { viewerState.open(KPdfSource.Url("https://example.com/other.pdf")) }) {
    Text("Load another document")
}
Wrap your KPdfSource in remember (or hoist it to a ViewModel) so that Compose recompositions do not create a new source object on every frame. If the source reference changes, rememberPdfViewerState treats it as a new document and restarts the load pipeline.
// Good — source is stable across recompositions
val source = remember(url) { KPdfSource.Url(url) }

// Avoid — creates a new object on every recomposition
val source = KPdfSource.Url(url)