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.