|
|
| |
| |
CroftSoft
/
Library
/
Tutorials
Rust-Dioxus Project Setup
2025 Dec 24 Wed
David Wallace Croft
2025-12-22: I updated this tutorial from Dioxus version 0.4 to 0.7.
For announcements of updates to this tutorial in the future, please monitor the
CroftSoft Update
weblog.
Contents
Summary
This article provides step-by-step instructions for using the Rust programming
language and the Dioxus user interface (UI) library to make a web application.
As explained in the overview, the project structure supports static prerendering
with client-side hydration.
Overview
A single page application (SPA) is a web application that downloads to the
client web browser as JavaScript or WebAssembly (Wasm) code with minimal
HTML.
Once the code starts running in the browser, it generates the HTML that it
needs for the SPA dynamically as the user navigates through the application.
The SPA code can also request data from a server and integrate into the
dynamically generated webpages client-side.
In contrast to web applications that require server-side rendering (SSR) to
integrate the HTML and data, an SPA can be served from a Content Delivery
Network (CDN). Unlike a static website served from a CDN, a search engine
crawler cannot load and read the webpages directly to find content since the SPA
is delivered as code which must be run in a client to dynamically generate the
HTML.
For this reason, some prefer SSR for search engine optimization (SEO).
For SEO, some tools let you prerender the static webpages for an SPA.
Once a static webpage and the SPA code are downloaded into the browser,
the SPA code integrates with the static webpage in a process
called client-side hydration.
This allows search engine crawlers to find HTML content directly from the CDN
while also permitting the SPA code to run in the browser.
Dioxus is a UI library for the Rust programming language which can
be deployed as an SPA by compiling the Rust source code to Wasm.
This article provides step-by-step instructions for setting up a Rust-Dioxus
project to make an SPA.
The project structure supports static prerendering with client-side hydration so
that the SPA can be served from a CDN.
Project Setup
-
Make a Rust project
-
Start by following the instructions in the
Rust Project Setup
tutorial
-
Then return to this webpage and proceed to the next step
-
Install the Dioxus Command-Line Interface (CLI) "dx"
cargo install dioxus-cli
-
Check the version of Dioxus
-
These instructions work with Dioxus 0.7.x
dx --version
-
Change your working directory to the new project directory
cd project-name/
-
Open the project directory in your code editor
code .
-
Use the Dioxus CLI to create the Dioxus configuration file Dioxus.toml
dx config init project-name
-
Change the "title" value in Dioxus.toml
-
The title will be displayed in the browser tab
-
In the following example, replace "Project Title" with your project title
[web.app]
title = "Project Title"
-
Use the cargo CLI to add the Dioxus dependency to your Cargo.toml file
-
With the "fullstack" and "router" features activated
-
Note: There should be no space after the comma in the following
cargo add dioxus -F fullstack,router
-
Append the following to your Cargo.toml file
[features]
default = ["web"]
server = ["dioxus/server"]
web = ["dioxus/web"]
-
Replace src/main.rs
use ::dioxus::prelude::*;
fn main() {
::dioxus::launch(App);
}
#[allow(non_snake_case)]
#[component]
pub fn App() -> Element {
rsx! {
div {
"Hello, world!"
}
}
}
-
Compile and serve the default project
-
After it finishes compiling, it will automatically open up in your browser
-
You should see "Hello, world!"
dx serve --open
-
Test the hot reload feature
-
In src/main.rs, change "world" to "World"
-
Observe that the browser automatically updates when you save your change
-
Stop the development server by pressing Control-C in the command-line terminal
-
Make a git commit of the Rust-Dioxus project in its current state
-
Later you can use git to compare the following customizations to this commit
git add .
git commit -m 'Dioxus hello world'
-
Push your commit to your remote repository
git push
-
Make a child directory for your static assets such as stylesheets and images
mkdir public
-
Make public/stylesheet.css
a {
color: white;
}
body {
background-color: black;
color: white;
}
button {
margin: 1rem;
}
-
Replace the code for src/main.rs again
-
Replace the placeholder value "project_name" with the name of your project
-
Use an underscore instead of a hyphen when you replace "project_name"
use ::dioxus::prelude::*;
use ::project_name::route::Route;
#[server(endpoint = "static_routes")]
async fn static_routes() -> Result<Vec<String>, ServerFnError> {
Ok(
Route::static_routes()
.into_iter()
.map(|route| route.to_string())
.collect::<Vec<_>>(),
)
}
fn main() {
dioxus::LaunchBuilder::new()
// Set the server config only if we are building the server target
.with_cfg(server_only! {
ServeConfig::builder()
// Enable incremental rendering
.incremental(
dioxus::server::IncrementalRendererConfig::new()
// Store static files in the public directory where other static
// assets like wasm are stored
.static_dir(
std::env::current_exe()
.unwrap()
.parent()
.unwrap()
.join("public")
)
// Don't clear the public folder on every build. The public folder
// has other files including the wasm binary and static assets
// required for the app to run
.clear_cache(false)
).enable_out_of_order_streaming()
})
.launch(|| {
rsx! {
Router::<Route> {}
}
});
}
-
Make src/lib.rs
pub mod component;
pub mod route;
-
Make src/route.rs
use super::component::colophon::Colophon;
use super::component::home::Home;
use super::component::template::Template;
use ::dioxus::prelude::*;
#[derive(Clone, Debug, PartialEq, Routable)]
pub enum Route {
#[layout(Template)]
#[route("/")]
Home {},
#[route("/colophon")]
Colophon {},
}
-
Make the component subdirectory
mkdir src/component/
-
Make src/component/mod.rs
pub mod colophon;
pub mod high_five;
pub mod home;
pub mod nav;
pub mod template;
-
Make src/component/colophon.rs
use super::high_five::HighFive;
use ::dioxus::prelude::*;
#[allow(non_snake_case)]
#[component]
pub fn Colophon() -> Element {
rsx! {
h1 { "Colophon Page" }
p {
"This website was created using the Rust library ",
a {
href: "https://dioxuslabs.com/",
target: "_blank",
"Dioxus",
},
"."
}
HighFive { }
}
}
-
Make src/component/high_five.rs
use ::dioxus::prelude::*;
#[allow(non_snake_case)]
#[component]
pub fn HighFive() -> Element {
let mut count: Signal<i32> = use_signal(|| 0);
rsx! {
h1 {
"High-Five counter: {count}"
}
button {
onclick: move |_mouse_event| {
count += 1;
},
"Up high!"
}
button {
onclick: move |_mouse_event| {
count -= 1;
},
"Down low!"
}
}
}
-
Make src/component/home.rs
use super::high_five::HighFive;
use ::dioxus::prelude::*;
#[allow(non_snake_case)]
#[component]
pub fn Home() -> Element {
rsx! {
h1 {
"Home Page"
}
p {
"This line is a placeholder for home page content."
}
HighFive { }
}
}
-
Make src/component/nav.rs
use super::super::route::Route;
use ::dioxus::prelude::*;
#[allow(non_snake_case)]
#[component]
pub fn Nav() -> Element {
rsx! {
nav {
ul {
li {
Link {
to: Route::Home {},
"Home"
}
}
li {
Link {
to: Route::Colophon {},
"Colophon"
}
}
}
}
}
}
-
Make src/component/template.rs
use super::super::route::Route;
use super::nav::Nav;
use ::dioxus::prelude::*;
#[allow(non_snake_case)]
#[component]
pub fn Template() -> Element {
const STYLESHEET: Asset = asset!("/public/stylesheet.css");
rsx! {
document::Link {
href: STYLESHEET,
rel: "stylesheet",
}
Nav { }
Outlet::<Route> {}
}
}
-
Compile and serve the customized project
dx serve --open
-
Test the code
-
If not already open, open your browser to
http://127.0.0.1:8080/
-
Click on the buttons on the Home page to verify that the Wasm is working
-
Click on the "Colophon" link in the navigation section
-
Click on the buttons on the Colophon page to verify that the Wasm is working
-
View the page source
-
Click on the "Home" link in the navigation section
-
Right-click on a webpage and select "View Page Source"
-
Note how the page content is not visible within the HTML
-
This will be fixed in a later step
-
Stop the development server by pressing Control-C in the command-line terminal
-
If you have a pre-existing target/server-release/ directory, delete it
-
In Dioxus version 0.7.2, this is required for the SSG option to work properly
rm -rf target/server-release/
-
Build the Single Page Application (SPA) with the release and SSG options
-
Note: Use "dx build" instead of "dx bundle"
-
In Dioxus version 0.7.2, "dx bundle" does not work with the SSG option properly
dx build --release --ssg
-
You can probably ignore the "ERROR wasm-opt failed" message
-
In Dioxus version 0.7.2, this is showing up during the build
-
This only shows up when you are doing a release build instead of a dev build
-
Install Node.js
-
See the installation instructions at
https://nodejs.org/
-
The Node.js installation includes the Node Package Manager (npm) and npx CLIs
-
The npm CLI is used in the next major section which is optional
-
The npx CLI is used in the following step to execute a development HTTP server
npm --version
npx --version
-
Serve the HTML and Wasm from your distribution directory
-
The following command will automatically open your browser
-
In the following, replace "project-name" with the name of your project
npx http-server target/dx/project-name/release/web/public -o -c-1
-
Verify that the webpage includes the text content
-
Press the reload button on your browser while holding the Shift key
-
Right-click on a webpage and select "View Page Source"
-
Note how the text content is visible within the HTML for search engines to find
-
Open the Colophon page directly in your browser
-
Enter the URL
http://127.0.0.1:8080/colophon/ in your browser toolbar
-
Note that the page loads without having to go to the Home page first
-
Click the buttons to verify that the Wasm is working
-
Stop http-server by pressing Control-C in the command-line terminal
-
Make a git commit of the Rust-Dioxus project in its current state
git add .
git commit -m 'Rust-Dioxus project setup'
-
Push your commit to your remote repository
git push
NPM Run Scripts
This optional section describes how to add Node Package Manager (npm) run
scripts to make development and testing of your Dioxus project easier.
-
Overwrite your project root directory .gitignore file with the following:
/dist
/node_modules
/target
-
Make a package.json file in your project root directory
-
Replace "project-name" with the name of your project in two places
{
"devDependencies": {
"http-server": "^14.1.1",
"prettier": "^3.7.4",
"shx": "^0.4.0"
},
"scripts": {
"build": "dx build --release --ssg",
"clean": "npm run clean1 && npm run clean2 && npm run clean3",
"clean1": "shx rm -rf target/dx/project-name/release",
"clean2": "shx rm -rf target/server-release",
"clean3": "shx rm -rf dist",
"copy": "shx cp -r target/dx/project-name/release/web/public dist/",
"dist": "npm run clean && npm run build && npm run copy",
"format": "prettier dist --ignore-path .prettierignore --write",
"serve": "http-server dist -c-1 -o",
"start": "dx serve --open",
"test": "npm run dist && npm run serve"
}
}
-
Install the dependencies
npm install
-
Test your npm run scripts
npm test
-
Update the README.md in your project root directory
-
Replace the placeholder values such as "Project Name" and "project-name"
# Project Name
- A description of Project Name
- Makes a Content Delivery Network (CDN)-compatible static HTML distribution
- Includes static prerendering with client-side hydration
## Utilities Installation
- Install the Rust command line utility "cargo"
- cargo is installed when you install Rust
- https://www.rust-lang.org/
- Install the Dioxus Command Line Interface (CLI) "dx"
- cargo install dioxus-cli
- https://github.com/DioxusLabs/dioxus/tree/master/packages/cli
- Install npm
- npm installs utilities such as prettier
- npm scripts run the dx and cargo commands
- npm can be installed by installing node.js
- https://nodejs.org/
## Quick Start
- npm install
- npm test
## Hot Reload
- cd project-name/
- npm install
- Installs the utility http-server to serve the HTML
- Installs the utility prettier to format the HTML
- Installs the utility shx to move files and remove directories
- npm start
- Used during development
- Builds, watches, and serves with hot reloading
- Automatically opens a browser window
- Make changes to the HTML in src/component/home.rs
- Or the CSS in public/stylesheet.css
- Note that the changes are updated in your browser as soon as you save
## Test Static Prerendering with Client-side Hydration
- npm test
- Deletes the build and distribution directories to start clean
- Makes the index.html page with the hydration code
- Launches http-server to serve the HTML
- Opens your browser to the home page
## Additional Run Script Commands
- npm run clean
- Deletes the build and distribution directories to start clean
- npm run copy
- Copies from the build to the distribution directory dist/
- npm run dist
- Runs the clean, build, and copy scripts
- Used to generate an SSG distribution in the dist/ directory
- The dist/ files can be hosted on a Content Delivery Network (CDN)
- npm run format
- Runs the "prettier" utility to format the generated files in dist/
- Useful for analyzing or debugging the generated files
- npm run serve
- Starts the http-server in dist/
- Opens the browser
- npm start
- Described in a previous section
- npm test
- Described in a previous section
## Links
- CroftSoft Rust-Dioxus Project Setup Tutorial
- https://www.croftsoft.com/library/tutorials/rust-dioxus-project-setup/
## History
- Initial release: YYYY-MM-DD
-
Stop the development server by pressing Control-C in the command-line terminal
-
Make a git commit of the Rust-Dioxus project in its current state
git add .
git commit -m 'npm run scripts'
-
Push your commit to your remote repository
git push
Links
-
Tutorial
-
Online Documentation
-
Videos
-
Example Source Code
-
Example Dioxus SSG Websites
© 2023 - 2025
CroftSoft Inc
|
|
| |
|
|
|