diff --git a/crates/tuono/src/source_builder/static_files.rs b/crates/tuono/src/source_builder/static_files.rs index 7422fb12..99c2c80a 100644 --- a/crates/tuono/src/source_builder/static_files.rs +++ b/crates/tuono/src/source_builder/static_files.rs @@ -20,10 +20,11 @@ pub const AXUM_ENTRY_POINT: &str = r##" // File automatically generated // Do not manually change it -use axum::extract::Request; +use axum::extract::{Path, Request}; use axum::response::Html; use axum::{routing::get, Router}; use tower_http::services::ServeDir; +use std::collections::HashMap; use tuono_lib::{ssr, Ssr}; use reqwest::Client; @@ -44,11 +45,11 @@ async fn main() { axum::serve(listener, app).await.unwrap(); } -async fn catch_all(request: Request) -> Html { +async fn catch_all(Path(params): Path>, request: Request) -> Html { let pathname = &request.uri(); let headers = &request.headers(); - let req = tuono_lib::Request::new(pathname, headers); + let req = tuono_lib::Request::new(pathname, headers, params); // TODO: remove unwrap diff --git a/crates/tuono_lib/src/request.rs b/crates/tuono_lib/src/request.rs index 59c9cdaf..0b4b8f5e 100644 --- a/crates/tuono_lib/src/request.rs +++ b/crates/tuono_lib/src/request.rs @@ -3,10 +3,11 @@ use std::collections::HashMap; use axum::http::{HeaderMap, Uri}; -#[derive(Debug, Copy, Clone)] +#[derive(Debug, Clone)] pub struct Request<'a> { uri: &'a Uri, headers: &'a HeaderMap, + pub params: HashMap, } /// Location must match client side interface @@ -21,8 +22,16 @@ pub struct Location<'a> { } impl<'a> Request<'a> { - pub fn new(uri: &'a Uri, headers: &'a HeaderMap) -> Request<'a> { - Request { uri, headers } + pub fn new( + uri: &'a Uri, + headers: &'a HeaderMap, + params: HashMap, + ) -> Request<'a> { + Request { + uri, + headers, + params, + } } pub fn location(&self) -> Location<'a> { diff --git a/crates/tuono_lib_macros/src/handler.rs b/crates/tuono_lib_macros/src/handler.rs index fef2731d..3ce8b70b 100644 --- a/crates/tuono_lib_macros/src/handler.rs +++ b/crates/tuono_lib_macros/src/handler.rs @@ -9,16 +9,21 @@ pub fn handler_core(_args: TokenStream, item: TokenStream) -> TokenStream { quote! { use axum::response::{Html, IntoResponse}; - use axum::extract::State; + use std::collections::HashMap; + use axum::extract::{State, Path}; use reqwest::Client; #item - pub async fn route(State(client): State, request: axum::extract::Request) -> Html { + pub async fn route( + Path(params): Path>, + State(client): State, + request: axum::extract::Request + ) -> Html { let pathname = &request.uri(); let headers = &request.headers(); - let req = tuono_lib::Request::new(pathname, headers); + let req = tuono_lib::Request::new(pathname, headers, params); let local_response = #fn_name(req.clone(), client).await; @@ -40,11 +45,15 @@ pub fn handler_core(_args: TokenStream, item: TokenStream) -> TokenStream { } } - pub async fn api(State(client): State, request: axum::extract::Request) -> axum::response::Response { + pub async fn api( + Path(params): Path>, + State(client): State, + request: axum::extract::Request + ) -> axum::response::Response { let pathname = &request.uri(); let headers = &request.headers(); - let req = tuono_lib::Request::new(pathname, headers); + let req = tuono_lib::Request::new(pathname, headers, params); let local_response = #fn_name(req.clone(), client).await; diff --git a/packages/tuono/src/router/hooks/useServerSideProps.tsx b/packages/tuono/src/router/hooks/useServerSideProps.tsx index b221253d..f447aa45 100644 --- a/packages/tuono/src/router/hooks/useServerSideProps.tsx +++ b/packages/tuono/src/router/hooks/useServerSideProps.tsx @@ -1,5 +1,6 @@ import { useState, useEffect, useRef } from 'react' import type { Route } from '../route' +import { useRouterStore } from './useRouterStore' const isServer = typeof document === 'undefined' @@ -20,6 +21,7 @@ export function useServerSideProps( serverSideProps: any, ): UseServerSidePropsReturn { const isFirstRendering = useRef(true) + const location = useRouterStore((st) => st.location) const [isLoading, setIsLoading] = useState( // Force loading if has handler route.options.hasHandler && @@ -41,15 +43,14 @@ export function useServerSideProps( return } // After client side routing load again the remote data - if (route.options.hasHandler && !data) { + if (route.options.hasHandler) { ;(async (): Promise => { setIsLoading(true) try { - const path = route.path === '/' ? '' : route.path - const res = await fetch(`/__tuono/data/${path}`) + const res = await fetch(`/__tuono/data${location.pathname}`) setData(await res.json()) } catch (error) { - // Handle here error + throw Error('Failed loading Server Side Data', { cause: error }) } finally { setIsLoading(false) } @@ -60,7 +61,7 @@ export function useServerSideProps( return (): void => { setData(undefined) } - }, [route.path]) + }, [location.pathname]) return { isLoading, data } }