1use actix_web::HttpResponse;
2use yew::html::BaseComponent;
3use yew::ServerRenderer;
4
5pub fn app_path(src: impl Into<String>) -> String {
7 let src: String = src.into();
8 if let Some(tail) = src.strip_prefix("/") {
9 let root = crate::app_root();
10 return format!("{root}{tail}");
11 }
12 src
13}
14
15pub async fn render<V, VM, E>(args: VM) -> Result<HttpResponse, E>
17where
18 V: BaseComponent,
19 V: BaseComponent<Properties = VM>,
20 VM: Send + 'static,
21{
22 let renderer = ServerRenderer::<V>::with_props(|| args);
23 let html = renderer.render().await;
24 let html = format!("<!DOCTYPE html>\n{html}");
26 Ok(HttpResponse::Ok()
27 .content_type("text/html; charset=utf-8")
28 .body(html))
29}
30
31pub async fn render_turbo_stream<V, VM, E>(args: VM) -> Result<HttpResponse, E>
33where
34 V: BaseComponent,
35 V: BaseComponent<Properties = VM>,
36 VM: Send + 'static,
37{
38 let renderer = ServerRenderer::<V>::with_props(|| args);
39 let html = renderer.render().await;
40 Ok(HttpResponse::Ok()
41 .content_type("text/vnd.turbo-stream.html")
42 .body(html))
43}
44
45pub fn redirect<E>(path: impl Into<String>) -> Result<HttpResponse, E> {
48 let path: String = app_path(path);
49 Ok(HttpResponse::SeeOther()
50 .insert_header(("Location", path))
51 .finish())
52}