30 days of Rust - Day Twenty Four - A blog with Yew
After having learnt a lot about how Rust works in the command line and backend, I wanted to actually find out if one can build client facing web applications with Rust and Rust only. To my surprise, the answer is Yes. Now, let's build a replica of my personal website masaimahapa.co.za with Rust.
A link to the full project on Github is here
Day 24 - Front end with Yew
Rust has a bunch of frameworks which allow us to write front end web applications. One that I came across is called Yew.
Yew is a modern Rust framework for creating multi-threaded front-end web apps using WebAssembly.
It is a component based framework, which took a lot of inspiration from React.js. It is also very fast, as you would expect from Rust. This is because Rust compiles down to WebAssembly (Wasm) which can run at native speeds in the browser. It is still very much a work in progress and should only get better with more adoption.
Dependencies
The dependencies for this project are;
-
Rust
-
Trunk
-
wasm32-unknown-unknown target. (This is the WebAssembly compiler and build target for Rust)
Make sure you have the latest version of Rust
rustup update
Secondly, install trunk;
cargo install trunk
lastly add the WebAssembly build target
rustup target add wasm32-unknown-unknown
The web page
In our Cargo.toml
file under dependencies, add the following line to install Yew;
yew = "0.19"
Thereafter we can now create the first component;
use yew::prelude::*;
#[function_component(App)]
fn app() -> Html {
html! {
<h1>{ "Masai Mahapa" }</h1>
}
}
fn main() {
yew::start_app::<App>();
}
In order for the component to come up in the browser, we need a page named index.html
. Rust will inject the components inside.
<!DOCTYPE html>
<html lang="en">
<head> </head>
<body></body>
</html>
starting the server
trunk serve --open
This now serves our web application into the browser. Any changes we make to our code will be recompiled and the server will refresh.
Add styling
We can add styling with CSS, either inline or by using an external .css file. For this project, I will use an external css file in the root folder, named styles.css
.
In order to tell trunk to include the css file every refresh we use the data-trunk
keyword when importing the css file on our html page.
<head>
<link data-trunk rel="css" href="styles.css" />
</head>
Creating more components
In order to create other components, we use the same syntax as shown above. So let's create the Navigation bar.
#[function_component(NavBar)]
pub fn navbar() -> Html {
html! {
<navbar>
<ul>
<li> <a href="#">{"Home"}</a></li>
<li> <a href="#"> {"Projects"}</a></li>
<li> <a href="#">{"Blog"}</a></li>
<li> <a href="#"> {"Contact"}</a></li>
</ul>
</navbar>
}
}
Notice that all the expressions are inside curly braces {}
.
Also, all components should have only one root element. This means, anytime we need more than one element, we should wrap it in a div
or fragment <> .. </>
.
Yew allows for two types of components, namely Functional
and Struct
. For this blog, I will use the functional ones.
Components can include other components, so now all the new components I am creating are descendants of the App
component. Right now it looks like this, with the other components created.
#[function_component(App)]
pub fn app() -> Html {
html! {
<div id="app">
<NavBar />
<Header />
<Bio />
<LatestPosts/>
</div>
}
}
A screenshot of the blog at the moment looks like
Next steps
This is obviously a proof of concept. There are many improvements that I still have to make. The next steps are to;
- Dynamically show the blog posts.
- Read the posts from a database.
- Have a page to show the content of each blog post
Conclusion
This was an incredible start to a project. Rust is proving to be a viable full stack language. Might this signal the end of Javascript? Well, I think I will be able to give a proper judgment at the end of this project.
Thanks for spending some time learning Rust with me. Until next time. Peace ✌🏼 .