Skip to main content

dioxus_cloudflare/
lib.rs

1//! # dioxus-cloudflare
2//!
3//! The missing bridge between Dioxus server functions and Cloudflare Workers.
4//!
5//! This crate connects Dioxus's `#[server]` macro (via the `axum_core` feature
6//! in `dioxus-fullstack`) to the Cloudflare Workers runtime. Write one function
7//! in your shared crate — it compiles to a client fetch stub *and* a Worker
8//! handler automatically.
9//!
10//! ## Quick Start
11//!
12//! **Worker entry point:**
13//!
14//! ```rust,ignore
15//! use worker::*;
16//! use dioxus_cloudflare::prelude::*;
17//!
18//! extern "C" { fn __wasm_call_ctors(); }
19//!
20//! #[event(fetch)]
21//! async fn fetch(req: Request, env: Env, _ctx: Context) -> Result<Response> {
22//!     unsafe { __wasm_call_ctors(); }
23//!     dioxus_cloudflare::handle(req, env).await
24//! }
25//! ```
26//!
27//! **Server function (shared crate):**
28//!
29//! ```rust,ignore
30//! use dioxus::prelude::*;
31//! use dioxus_cloudflare::prelude::*;
32//!
33//! #[server]
34//! pub async fn get_user(id: String) -> Result<User, ServerFnError> {
35//!     let db = cf::d1("DB")?;
36//!     // ...
37//! }
38//! ```
39//!
40//! **Client component (calls it like a normal function):**
41//!
42//! ```rust,ignore
43//! let user = get_user("abc".into()).await;
44//! ```
45//!
46//! ## Architecture
47//!
48//! ```text
49//! Client WASM                    Cloudflare Worker
50//! ┌──────────┐    fetch()    ┌─────────────────────┐
51//! │ #[server] │ ───────────▶ │ handle(req, env)     │
52//! │ generates │              │   ↓ set_context()    │
53//! │ POST to   │              │   ↓ worker→http req  │
54//! │ /api/...  │              │   ↓ Axum dispatch    │
55//! │           │ ◀─ stream ─  │   ↓ http→worker resp │
56//! └──────────┘               └─────────────────────┘
57//! ```
58
59mod bindings;
60mod context;
61mod cookie;
62mod error;
63mod handler;
64pub mod prelude;
65mod session;
66#[cfg(feature = "ssr")]
67mod ssr;
68#[cfg(feature = "ssr")]
69mod streaming;
70mod websocket;
71
72/// Access Cloudflare Worker bindings and request context from inside
73/// `#[server]` functions.
74///
75/// ## Binding shortcuts
76///
77/// - [`cf::d1()`] — D1 database (combines env + binding lookup + error conversion)
78/// - [`cf::kv()`] — Workers KV namespace
79/// - [`cf::r2()`] — R2 bucket
80/// - [`cf::durable_object()`] — Durable Object namespace
81/// - [`cf::queue()`] — Queue producer (requires `queue` feature)
82/// - [`cf::secret()`] — encrypted secret (set via `wrangler secret put`)
83/// - [`cf::var()`] — plaintext environment variable (set in `[vars]`)
84///
85/// ## Raw access
86///
87/// - [`cf::env()`] — the full Worker `Env` (for bindings without a shorthand)
88/// - [`cf::req()`] — the raw `worker::Request` (headers, IP)
89///
90/// ## Incoming cookies
91///
92/// - [`cf::cookie()`] — read a named cookie from the request
93/// - [`cf::cookies()`] — read all cookies from the request
94///
95/// ## Outgoing cookies
96///
97/// - [`cf::set_cookie()`] — queue an HttpOnly auth cookie (secure defaults)
98/// - [`cf::set_cookie_with()`] — queue a cookie with custom options
99/// - [`cf::clear_cookie()`] — queue a cookie-clearing header (logout)
100///
101/// Outgoing cookies are queued in thread-local storage and applied to the
102/// response by [`handle`] — no `&mut Response` needed inside server functions.
103///
104/// ## Sessions
105///
106/// - [`cf::session()`] — load the session (async first call, cached after); returns [`Session`](cf::Session) handle
107///
108/// Requires `.session(SessionConfig::kv("SESSIONS"))` on the [`Handler`].
109///
110/// ## WebSocket helpers
111///
112/// - [`cf::websocket_upgrade()`] — create a `WebSocketPair` and 101 response in one call
113/// - [`cf::websocket_pair()`] — create a raw `WebSocketPair` for custom handling
114pub mod cf {
115    pub use crate::bindings::{d1, durable_object, kv, r2, secret, var};
116    #[cfg(feature = "queue")]
117    pub use crate::bindings::queue;
118    pub use crate::context::{env, req};
119    pub use crate::cookie::{
120        clear_cookie, cookie, cookies, set_cookie, set_cookie_with, CookieBuilder, SameSite,
121    };
122    pub use crate::session::{session, Session};
123    pub use crate::websocket::{websocket_pair, websocket_upgrade};
124}
125
126pub use error::{CfError, CfResultExt};
127pub use handler::{handle, Handler};
128pub use session::SessionConfig;
129
130// Re-export ServerFnError so error.rs can reference it without users needing
131// to add dioxus as a direct dependency just for the error type.
132#[doc(hidden)]
133pub use dioxus::prelude::ServerFnError;