The Rust framework for the modern web
fn index_page<G: Html>(cx: Scope, state: &IndexStateRx) -> View<G> {
view! { cx,
h1 { (format!(
"Hello, {}!",
state.name.get()
)) }
input(
placeholder = "Name",
bind:value = state.name
)
a(href = "about") { "About" }
}
}
#[derive(Serialize, Deserialize, Clone, ReactiveState)]
#[rx(alias = "IndexStateRx")]
struct IndexState {
name: String,
}
// This function will be run when you build your app, to generate default state
// ahead-of-time
#[engine_only_fn]
async fn get_build_state(_info: StateGeneratorInfo<()>) -> IndexState {
IndexState {
name: "User".to_string(),
}
}
Generate state, on your terms
Perseus apps can generate state whenever they like and pass it to Sycamore, one of the fastest web frameworks in the world.
fn post_page<G: Html>(cx: Scope, state: &PostRx) -> View<G> {
view! { cx,
h1 { (state.title.get()) }
p { (state.author.get()) }
div(
dangerously_set_inner_html = &state.content.get()
)
}
}
// ...
// This function will be run for each path under `/post/` to generate its state
#[engine_only_fn]
async fn get_build_state(
StateGeneratorInfo { path, .. }: StateGeneratorInfo<()>,
) -> Result<Post, BlamedError<MyError>> {
let raw_post = match get_post_for_path(path) {
Ok(post) => post,
// If the user sends us some bogus path with incremental generation,
// return a 404 appropriately
Err(err) => {
return Err(BlamedError {
blame: ErrorBlame::Client(Some(404)),
error: MyError(err),
})
}
};
let html_content = parse_markdown(raw_post.content);
let post = Post {
title: raw_post.title,
author: raw_post.author,
content: html_content,
};
Ok(post)
}
#[engine_only_fn]
async fn get_build_paths() -> BuildPaths {
BuildPaths {
// These will all become URLs at `/post/<name>`
paths: vec![
"welcome".to_string(),
"really-popular-post".to_string(),
"foobar".to_string(),
],
// Perseus supports helper state, but we don't need it here
extra: ().into(),
}
}
I18nInternationalization
that just worksJust add translations using Fluent, and your app can be set up in seconds in multiple languages, with automatic user locale detection.
.locales_and_translations_manager(
"en-US", // Default locale
&["fr-FR", "es-ES"], // Other supported locales
)
// ...
// Our landing page. Going to `/` will cause a redirect to `/en-US`,
// `/es-ES`, or `/fr-FR` based on the user's locale settings in their browser,
// all automatically. If nothing matches, the default locale (`en-US`) will be
// used.
fn index_page<G: Html>(cx: Scope) -> View<G> {
view! { cx,
h1 { (t!(cx, "greeting")) }
}
}
// `translations/en-US.ftl`:
// greeting = Hello, world!
// `translations/es-ES.ftl`:
// greeting = Β‘Hola, mundo!
// `translations/fr-FR.ftl`:
// greeting = Bonjour, le monde!
Fast. Crazy. Fast.
Underlying platform? Rust.
Target platform? WebAssembly.
Lighthouse scores? π―
Performance (Desktop)
Performance (Mobile)
Best Practices