Masai Mahapa

30 days of Rust - Day Twenty Four - A blog with Yew

30 days of rust - day Twenty Four 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

30 days of rust - blog masai

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 ✌🏼 .

Share