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//! │           │ ◀── JSON ──  │   ↓ http→worker resp │
56//! └──────────┘               │   ↓ clear_context()  │
57//!                            └─────────────────────┘
58//! ```
59
60mod bindings;
61mod context;
62mod cookie;
63mod error;
64mod handler;
65pub mod prelude;
66
67/// Access Cloudflare Worker bindings and request context from inside
68/// `#[server]` functions.
69///
70/// ## Binding shortcuts
71///
72/// - [`cf::d1()`] — D1 database (combines env + binding lookup + error conversion)
73/// - [`cf::kv()`] — Workers KV namespace
74/// - [`cf::r2()`] — R2 bucket
75///
76/// ## Raw access
77///
78/// - [`cf::env()`] — the full Worker `Env` (Durable Objects, Queues, etc.)
79/// - [`cf::req()`] — the raw `worker::Request` (headers, IP)
80///
81/// ## Incoming cookies
82///
83/// - [`cf::cookie()`] — read a named cookie from the request
84/// - [`cf::cookies()`] — read all cookies from the request
85///
86/// ## Outgoing cookies
87///
88/// - [`cf::set_cookie()`] — queue an HttpOnly auth cookie (secure defaults)
89/// - [`cf::set_cookie_with()`] — queue a cookie with custom options
90/// - [`cf::clear_cookie()`] — queue a cookie-clearing header (logout)
91///
92/// Outgoing cookies are queued in thread-local storage and applied to the
93/// response by [`handle`] — no `&mut Response` needed inside server functions.
94pub mod cf {
95    pub use crate::bindings::{d1, kv, r2};
96    pub use crate::context::{env, req};
97    pub use crate::cookie::{
98        clear_cookie, cookie, cookies, set_cookie, set_cookie_with, CookieBuilder, SameSite,
99    };
100}
101
102pub use error::{CfError, CfResultExt};
103pub use handler::handle;
104
105// Re-export ServerFnError so error.rs can reference it without users needing
106// to add dioxus as a direct dependency just for the error type.
107#[doc(hidden)]
108pub use dioxus::prelude::ServerFnError;