24 Oct 24

Yew and Tailwind

Pre-requisite steps:

  • Install Rust: curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

  • Install the WebAssembly target: rustup target add wasm32-unknown-unknown

  • Install Trunk: cargo install --locked trunk

After you follow the pre-requisite steps, let’s create a new Yew app and configure it to use Tailwind.

  • Create a new app: cargo new yew-app

  • Change into the directory: cd yew-app

  • Try it: cargo run

If your environment is setup correctly, you should see:

Hello World!

Let’s turn the app into a Web app. First step is to add Yew to the dependencies in the Cargo.toml file:

[dependencies]  
yew = { git = "https://github.com/yewstack/yew/", features = ["csr"] }

Now if we run cargo run again, we’ll see the dependency is added, but the output is still the same. Let’s change that by modifying the entry point via the src/main.rs file and have it return some HTML.

Update src/main.rs file with the following:

use yew::prelude::*;

#[function_component]
fn App() -> Html {
    html! {
        <div>
            <p>{ "Hello from Yew!" }</p>
        </div>
    }
}

fn main() {
    yew::Renderer::<App>::new().render();
}

And we need a template, so let’s add an index.html file with the following:

<!doctype html>
<html>
    <head>
        <meta charset="utf-8" />
        <title>Yew App</title>
    </head>
    <body></body>
</html>

When we run the app now (via Trunk, not Cargo), we’ll enter the entry point which will mount our App and render the output into the <body> tag of our template.

Let’s check it out in the browser:

trunk serve --open

Congratulations, we have a “hello world” Yew app. Let’s style it with Tailwind.

Next, let’s install the Tailwind CLI by finding the correct build for your system here:

https://github.com/tailwindlabs/tailwindcss/releases/latest

Then run the following(in your PATH), filling in your desired build:

curl -sLO https://github.com/tailwindlabs/tailwindcss/releases/latest/download/tailwindcss-macos-arm64

mv tailwindcss-macos-arm64 tailwind
chmod +x tailwind

NOTE: if you use an environment manager like rbenv for Ruby, you may run into a conflict. Run which tailwind to see if you are pointed at the newly downloaded executable, or a previously installed shim. If needed, adjust your PATH accordingly.

Back in our Yew app directory, let’s initialize Tailwind.

tailwind init

This generates our config file. We’ll specify the files that contain HTML with tailwind utility classes.

Open the config file and add our two file paths to the content array:

module.exports = {
  content: ["index.html", "./src/*.rs"],
  theme: {
    extend: {},
  },
  plugins: [],
};

So now, if we specify any Tailwind classes in either the index.html file, or our Rust files that return HTML our next step will know to compile those classes into a stylesheet file our app will use.

We need a css file that brings in Tailwind and allows us to write any custom styles. We’ll then add a hook to Trunk to compile all of the needed style classes into a stylesheet file that we’ll include in the head of our app.

Let’s add a style directory and create a file inside it called classes.css.

mkdir style && touch style/classes.css

Let’s add the base Tailwind classes to that file:

@tailwind base;
@tailwind components;
@tailwind utilities;

Next let’s create the file we will have the Trunk hook compile into.

touch style/application.css

We’ll need to add that file to our index.html file as well, in the <HEAD>.

<link data-trunk rel="css" href="style/application.css" />

Let’s add some Tailwind utility classes to our markup in the main.rs file to see it work:

<div class="p-8">
    <p class="font-medium text-red-500">{ "Hello from Yew!" }</p>
</div>

Last step before we refresh. Let’s tell Trunk to compile the css via a hook:

Create a config file for Trunk in the root of the directory:

touch trunk.toml

Paste in the following:

[[hooks]]
stage = "pre_build"
command = "tailwind"
command_arguments = ["-i", "style/classes.css", "-o", "style/application.css"]

This adds a command for Trunk to run during serve that will use the Tailwind CLI and compile all the Tailwind classes our app needs into the application.css file. It scans the files we configured in the Tailwind config. So when we add a new class to our <p> tag, Trunk will see the change, rerun, including the above hook and we’ll see the new style applied when the browser refreshes.

trunk serve --open

We did it! That is a “hello world” Yew app styled with Tailwind. Go forth and “flex” your new found knowledge!

Music companion of this post: TriplexxxGirlfriend - Front 242

What I am working on currently: A Yew app and Rust based API, I’m also introducing Webhooks to Schemabook.