Skip to main content

Reflex PDF viewer component and app.

Project description

Reflex PDF Viewer + App

This repository includes the source (under /src) for a Python package reflex_pdf that provides both

  • a reusable Reflex custom component package reflex_pdf.components and
  • a standalone Reflex application reflex_pdf_app.apps.

Prerequisites

  • Python 3.10 to 3.13, including pip.

Note: Current Reflex/Pydantic v1 compatibility emits runtime warnings on Python 3.14+, so production deployments should use Python 3.10-3.13.

reflex-pdf.components

A PDF viewer component for Reflex, built on top of react-pdf.

Install

pip install reflex-pdf

Use in your Reflex app

import reflex as rx
from reflex_pdf import Document, Page


class State(rx.State):
    current_page: int = 1
    n_pages: int = 1

    @rx.event
    def load_success(self, info: dict):
        self.n_pages = info.get("numPages", 1)


def index():
    return rx.vstack(
        rx.heading("Reflex PDF preview", size="8"),
        Document.create(
            Page.create(page_number=State.current_page),
            file="https://mozilla.github.io/pdf.js/web/compressed.tracemonkey-pldi-09.pdf",
            on_load_success=State.load_success,
        ),
    )


app = rx.App()
app.add_page(index)

Add this to your rxconfig.py:

import reflex as rx

config = rx.Config(
    app_name="your_app",
    frontend_packages=["react-pdf@9.1.1"],
)

Standalone app: reflex_pdf_app

Run from the repository root:

python -m reflex_pdf.apps.run_app

This script will:

  1. Prepare runtime directories for Reflex state and build artifacts
  2. Ensure bun is available for Reflex frontend builds
  3. Ensure Node.js is available (>= 22.14.0 in both dev and prod single-port modes)
  4. Start the app in src/reflex_pdf/apps/ using the current Python environment

To prebuild/compile artifacts without starting the server, run (this uses reflex export --no-zip):

python -c "from reflex_pdf.apps.run_app import prebuild; prebuild()"

Run modes:

  • local default: dev mode on frontend 3000 and backend 8000
  • Codespaces default: prod single-port mode on 3000

Environment overrides:

  • REFLEX_RUN_MODE:
    • dev
    • prod-single-port
  • REFLEX_TRANSPORT:
    • websocket
    • polling
  • REFLEX_FRONTEND_PORT and REFLEX_BACKEND_PORT (dev mode)
  • REFLEX_SINGLE_PORT (prod single-port mode)

For Codespaces, single-port mode avoids separate backend tunnel auth for /_event. The launcher defaults REFLEX_TRANSPORT=polling in Codespaces for compatibility with forwarded-port browser sessions.

Backend event endpoint

This app already uses Reflex's built-in backend event endpoint (/_event) for all state updates (for example State.set_pdf_url).

Because /_event is Reflex's internal event transport rather than a FastAPI route, it is not exposed through Swagger/OpenAPI by default.

For MFE-style integration, the host can set the PDF URL from the same browser session in either of these ways:

  1. Initial URL in iframe source query string:
    • https://<viewer-host>/?pdf=<encoded_pdf_url>
  2. Runtime updates via postMessage to the iframe:
iframe.contentWindow.postMessage(
  { type: "reflex-pdf:set-url", url: "https://example.com/file.pdf" },
  "*",
);

Both approaches update only that user session (no separate backend request needed).

Query-string rule: only one parameter is accepted (pdf). If the URL contains more than one parameter, the app shows: "At most one query parameter is supported (?pdf=<url_encoded_pdf_url>). If your PDF URL contains query arguments, URL encode the entire value."

Example that must be encoded:

  • raw (invalid): /?pdf=https://example.com/file.pdf?token=abc&download=1
  • encoded (valid): /?pdf=https%3A%2F%2Fexample.com%2Ffile.pdf%3Ftoken%3Dabc%26download%3D1

The viewer uses a single URL state (pdf_url) for both initialization and runtime updates:

  • ?pdf=... initializes pdf_url when the page loads.
  • postMessage with { type: "reflex-pdf:set-url", url } updates that same pdf_url in-session.

You can customize URL normalization by registering either:

  • a UrlPreprocessor implementation (ABC), or
  • a lightweight hook function.
from reflex_pdf.apps.url_preprocessor import set_url_preprocess_hook

set_url_preprocess_hook(lambda url: url.replace("http://", "https://"))

Reset to default no-op behavior:

set_url_preprocess_hook(None)

For automation/integration testing outside the browser session, you can post the same event with post_pdf_url_event:

from reflex_pdf.apps.event_test_client import post_pdf_url_event

post_pdf_url_event("http://127.0.0.1:3000", "https://mozilla.github.io/pdf.js/web/compressed.tracemonkey-pldi-09.pdf")

Development

pip install -e .

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

reflex_pdf-0.0.4-py3-none-any.whl (18.3 kB view details)

Uploaded Python 3

File details

Details for the file reflex_pdf-0.0.4-py3-none-any.whl.

File metadata

  • Download URL: reflex_pdf-0.0.4-py3-none-any.whl
  • Upload date:
  • Size: 18.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.5

File hashes

Hashes for reflex_pdf-0.0.4-py3-none-any.whl
Algorithm Hash digest
SHA256 36fa3c9609f33c330bb5f36cab5de0dde30d1f176f8eaaef6b04f1f83900f5ac
MD5 e5f8c18d65888e7b8e3731895a77f3e6
BLAKE2b-256 b24e163c37039dbc1e941403a3976762f5368df6bb483ac733b5ea35398f93e0

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page