Hey friends, is there an easy example that explain...
# kobweb
s
Hey friends, is there an easy example that explains how to share layouts between pages in Kobweb? I have a
TopBar
composable that I want to share between multiple destinations/pages.
d
Take a look at
kobweb create app
which shares the
NavHeader
composable across multiple pages (called by the PageLayout composable). You can also look at my blog site, which defines two page layouts, one which delegates to the other: https://github.com/bitspittle/bitspittle.dev/blob/main/site/src/jsMain/kotlin/dev/bitspittle/site/components/layouts/PageLayout.kt https://github.com/bitspittle/bitspittle.dev/blob/main/site/src/jsMain/kotlin/dev/bitspittle/site/components/layouts/BlogLayout.kt
s
Okay so if I understand it correct, there's nothing that Kobweb is supposed to do in this situation The user will basically create a
Scaffold-like
composable that he will manually have to use in all his
@Page
composables?
The packages
layouts
,
sections
, and
widgets
are not special keywords (like in frameworks like Next.js) and give people just a way to organise their code if they didn't already know how to do so?
s
yes, but isn't this how compose also works on other platforms?
s
Absolutely, and I have no issues whatsoever Just wanted to make sure I'm not missing anything that the framework might be doing
s
yeayeah. the big difference might be that @Page is a hard cut, whereas in android you can have a router just inside the scaffold content
s
Precisely
s
but one thing that kobweb does is convert md files from resources to pages during the build <https://github.com/varabyte/kobweb?tab=readme-ov-file#markdown>
πŸ†— 1
d
Folks here might be interested by this proposal that is currently on hold, as we've been waiting for a (fixed!!) bug to propagate its way through to a stable Compose release. https://docs.google.com/document/d/1bSREBgBaWMCKYPYgfiOFnq8AOBsqUZ-W5DUpr62euaU I believe that bug fix will land in Compose 1.8, at which point I'll re-review the document and prioritize it. With that approach, old Kobweb sites will continue to work just fine, but moving forward users would be able to use a new
@DefaultLayout
annotation that would apply to all pages automatically.
πŸ™Œ 1
πŸ™ŒπŸ» 1
s
This is great news! Thanks for letting us know. For now, is there a way to catch all route navigations on the same page? So that I could manually switch between specific parts of the screen?
d
What's the specific example?
s
Let's assume
JIRA
as an example When you open a ticket's dialog on the same page, it routes to the same URL with a
#
parameter added to it, essentially staying on the same page (not needing to recompose it), but animating-in the dialog And when you need to close the dialog, just navigate to the same page without the
#
parameter
s
you can totally do this. just manipulate the url with the same button that opens the dialog
s
The navigation part is understood But wouldn't the whole page recompose if I perform this navigation operation even if to the same URL?
s
the trick is that you don't really 'navigate'
you just open the dialog
d
I'm pretty sure just adding the fragment doesn't recompose, but I'd need to check
s
haven't noticed any issues regarding that. but some parts need to be recomposed anyway to make way for the dialog you're showing to the user
d
Like, if you click a random element in the header here, it updates the URL, but it doesn't look like it recomposes the page: https://bitspittle.dev/blog/2022/kotlin-site
s
Correct So let's say that I only have a single page named
MyPage
that I want all routes to respond to e.g. localhost:8080/routeA localhost:8080/routeA/B/C localhost:8080/routeB/C/D and so on all routes should open up the same page, so that I could then detect which URL has been opened and what section to display
d
Sounds like a use-case for dynamic routes?
s
Probably.. I'll have to test Not sure yet
Just note I don't support catching multiple dirs
s
I'm not sure if you can change the actual url without making the browser route though. adding a query parameter is different
πŸ‘ 1
s
Understood Thank you both David and S. for your time and effort πŸ™Œ Much appreciated
πŸ‘ 1
🀝 1
s
seems like it should also work for the entire url https://developer.mozilla.org/en-US/docs/Web/API/History/pushState
d
BTW if the list of routes in concrete -- like, you want one page to handle 5 different specific routes for some reason, you can always do this:
Copy code
// Watch.kt
@Page
@Composable
fun WatchPage() {
   /* ... */
}

@Page("/alt-watch")
@Composable
fun AltWatchPage() { WatchPage() }

@Page("/watch/a/b")
@Composable
fun WatchABPage() { WatchPage() }
etc.
(Dynaming routes are useful when you should handle ANY incoming route, e.g.
/watch/{video-id}
)
s
Thanks for that Now that I think about my problem, could I have explained it by simply saying that I want the Single Page App (SPA) experience instead of the Multi-page experience? πŸ˜‚ But I feel that's out of scope for Compose-HTML apps because SPA is a React-only concept?
d
So you basically want dynamic routes that capture all possible incoming routes
I mean you could get close by registerying, say, four dynamic routes
Copy code
@Page("/{a}")
@Page("/{a}/{b}")
@Page("/{a}/{b}/{c}")
@Page("/{a}/{b}/{c}/{d}")
and have those delegate to some target composable method
Note that Compose HTML is an SPA framework. Kobweb exists more to layer a multi-site experience on top of it. Compose HTML is a pretty good mapping, conceptually, to React; Kobweb to NextJS.
So let's file a bug for that. We should add it into Kobweb eventually.
(Writing it up now)
If we can get that proposal working, then you could get a "handle all routes" SPA app with a single
@Page("{...slug}")
πŸ™Œ 1
s
Wow.. this is an amazing proposal πŸ™Œ Thank you very much David You're so helpful!
d
You're welcome. Note that it's not something I'll be able to prioritize for a little while. I'm hoping the hacky approach above (https://kotlinlang.slack.com/archives/C04RTD72RQ8/p1735251252110829?thread_ts=1735122301.972459&amp;cid=C04RTD72RQ8) can tide you over for now?
s
It's okay for now, not an immediate thing I'll probably not implement routing in this iteration For now I'm planning to just create a single
@Page
and switch its content on user interaction Maybe create my own variant of
AnimatedContent
composable
d
Sounds good. Good luck! If you make progress, let me know, and I'll see if it makes sense to include it into Kobweb.
(Only if you would want that of course, not trying to steal anything from anyone)
s
Oh no worries at all πŸ˜‚ Happy to contribute in whatever capacity I can
thank you color 1
d
@Shubham Singh Christmas gift for you. Adding catch all routes sounded fun so I decided to add them. If you set your Kobweb version to
0.20.1-SNAPSHOT
, you should now be able to do this:
Copy code
// com/example/pages/Index.kt

@Page("{...path?}")
@Composable
fun CatchAllPage() {
    val ctx = rememberPageContext()
    println(ctx.route.params.getValue("path"))
}
You can read more here: https://github.com/varabyte/kobweb/tree/0.20.1#catch-all-dynamic-routes If you are able to give it a try, please let me know if you run into any problems.
πŸŽ„ 1
s
Sweet! Thanks a bunch Santa πŸŽ…πŸ˜„πŸŽ„
😁 1
d
In 2025 I should take a page from St Nick's book and get me some slave labor elves... I mean, "open source contributors"
πŸ˜‚ 1
s
Happy New Year to you and your family by the way πŸ™ŒπŸΌ
thank you color 1