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.componentsand - 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:
- Prepare runtime directories for Reflex state and build artifacts
- Ensure bun is available for Reflex frontend builds
- Ensure Node.js is available (>= 22.14.0 in both dev and prod single-port modes)
- 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:
devmode on frontend3000and backend8000 - Codespaces default:
prod single-portmode on3000
Environment overrides:
REFLEX_RUN_MODE:devprod-single-port
REFLEX_TRANSPORT:websocketpolling
REFLEX_FRONTEND_PORTandREFLEX_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:
- Initial URL in iframe source query string:
https://<viewer-host>/?pdf=<encoded_pdf_url>
- Runtime updates via
postMessageto 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 (
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=...initializespdf_urlwhen the page loads.postMessagewith{ type: "reflex-pdf:set-url", url }updates that samepdf_urlin-session.
You can customize URL normalization by registering either:
- a
UrlPreprocessorimplementation (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 .
Metadata
Release files for reflex-pdf 0.0.4
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| reflex_pdf-0.0.4-py3-none-any.whl | Python 3 | none | any | Details |
Release files / reflex_pdf-0.0.4-py3-none-any.whl
| Download URL | reflex_pdf-0.0.4-py3-none-any.whl |
|---|---|
| Size | 18.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
36fa3c9609f33c330bb5f36cab5de0dde30d1f176f8eaaef6b04f1f83900f5ac
|
|
BLAKE2b-256 checksum How to use checksums |
b24e163c37039dbc1e941403a3976762f5368df6bb483ac733b5ea35398f93e0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.5
|