You are currently viewing the docs for Dioxus 0.5.7 which is no longer maintained.

Server-Side Rendering

For lower-level control over the rendering process, you can use the dioxus-ssr crate directly. This can be useful when integrating with a web framework that dioxus-fullstack does not support, or pre-rendering pages.

Setup

For this guide, we're going to show how to use Dioxus SSR with Axum.

Make sure you have Rust and Cargo installed, and then create a new project:

cargo new --bin demo
cd demo

Add Dioxus and the ssr renderer as dependencies:

cargo add dioxus@0.5.0
cargo add dioxus-ssr@0.5.0

Next, add all the Axum dependencies. This will be different if you're using a different Web Framework

cargo add tokio --features full
cargo add axum

Your dependencies should look roughly like this:

[dependencies]
axum = "0.7"
dioxus = { version = "*" }
dioxus-ssr = { version = "*" }
tokio = { version = "1.15.0", features = ["full"] }

Now, set up your Axum app to respond on an endpoint.

src/ssr.rs
use axum::{response::Html, routing::get, Router};
use dioxus::prelude::*;

#[tokio::main]
async fn main() {
    let listener = tokio::net::TcpListener::bind("127.0.0.1:3000")
        .await
        .unwrap();

    println!("listening on http://127.0.0.1:3000");

    axum::serve(
        listener,
        Router::new()
            .route("/", get(app_endpoint))
            .into_make_service(),
    )
    .await
    .unwrap();
}

And then add our endpoint. We can either render rsx! directly:

src/ssr.rs
async fn app_endpoint() -> Html<String> {
    // render the rsx! macro to HTML
    Html(dioxus_ssr::render_element(rsx! { div { "hello world!" } }))
}

Or we can render VirtualDoms.

src/ssr.rs
async fn app_endpoint() -> Html<String> {
    // create a component that renders a div with the text "hello world"
    fn app() -> Element {
        rsx! { div { "hello world" } }
    }
    // create a VirtualDom with the app component
    let mut app = VirtualDom::new(app);
    // rebuild the VirtualDom before rendering
    app.rebuild_in_place();

    // render the VirtualDom to HTML
    Html(dioxus_ssr::render(&app))
}

Finally, you can run it using cargo run rather than dx serve.

Multithreaded Support

The Dioxus VirtualDom, sadly, is not currently Send. Internally, we use quite a bit of interior mutability which is not thread-safe.Send, it is possible to render a VirtualDom immediately to a String – but you cannot hold the VirtualDom across an await point. For retained-state SSR (essentially LiveView), you'll need to spawn a VirtualDom on its own thread and communicate with it via channels or create a pool of VirtualDoms.must remain on the thread it started. We are working on loosening this requirement.