My project now supports exporting your Compose for...
# compose-web
d
My project now supports exporting your Compose for Web project in a format that allows it to be served by static website hosting providers. If this is something you might be excited about, you can read more here: https://bitspittle.dev/blog/2022/staticdeploy
🙌🏻 1
🔥 10
👀 3
🙌 1
h
Sounds interesting, so you split the compose code into different single html files?
d
Yes
You pull the page down, it renders immediately, then the JavaScript gets downloaded and runs your Compose for Web code, which essentially replaces the DOM with itself.
r
Does it work somehow with dynamic routes?
d
You can still use query parameters though
a
I'm a little confused by this. I've been serving static GitHub Pages built with compose web for a while. The build artifact is a single js file, so static hosting works fine. What problem is this solving?
d
How many pages do you have in your site?
a
Multiple.
d
So let's say you have page "a", "b", and "c" or whatever
What happens if you type
<https://io.whatever.github/github-project-pages/path/to/a>
?
a
It loads that page, which has a js script tag that loads the js? Same as any html page?
d
If you don't have something like "docs/path/to/a.html" in GHP, you get a 404, don't you?
a
❤️ 1
That's written with compose-web
d
Thanks! Let me look at the project
I'm probably looking in the wrong place? https://github.com/ajalt/colormath/tree/master/docs
d
So what happens when you compile that?
(I hope I'm not coming across snide or defensive, I'm genuinely curious and asking questions here)
a
I get a js file which I copy to
/gradient.js
, which is loaded from the html: https://github.com/ajalt/colormath/blob/master/website/gradient/src/jsMain/resources/index.html
h
I understand: kobweb goal is to increase performance by storing the initial compose rendered page in a static html and reload changes dynamically with compose web after loading the (big) js file. Currently, if you create different pages with an empty index file, the compose js file needs to be downloaded at start, which results into an empty page until js file is loaded. correct me if I am wrong 😄
d
That's definitely an advantage! But I was under the impression that a single "index.html" + "js" file was not compatible with most static website hosting services
r
@David Herman I think @AJ Alt has created index.htmls for each route on his site. See: https://github.com/ajalt/colormath/tree/gh-pages. For example, https://github.com/ajalt/colormath/tree/gh-pages/gradient. @AJ Alt Correct me if I'm wrong but all the navigation and menus and stuff on your docs site are already static. Its just the applications that are compose-based and embedded.
r
Generally you need a configuration which redirects 404 to the same index.html. Most services can do that, because typical react apps need this as well.
h
It depends on the router: HashRouter supports SPA on static website hosting service via
<http://foo.com/#/a|foo.com/#/a>
. Otherwise, you need to configure the service to redirect 404 to the index file and use a BrowserRouter
d
Ah, if you can configure a redirect that would work
r
Your idea is basically a pre-rendering for kotlin/js (https://create-react-app.dev/docs/pre-rendering-into-static-html-files/).
d
But yeah, I'm still coming up to speed but if what @rocketraman is saying is correct, you had to do extra work to generate that layout
Yeah, I'm pre-rendering
Note that Kobweb doesn't exist to export static sites, that's not why I wrote it
but quite a few people who tried it out wanted to then export it to a static site host, which is the feature I added here
r
It's made really nice and I want to try copy this this for my KVision (sorry 😉)
d
I saw Google Cloud Storage had the ability to reroute 404s to any html file but I didn't see that on GitHub Pages or Netlify when I looked (although I could have missed it)
@Robert Jaros ✌️ It's open source, good luck my friend!
h
Nope, GHP does not support any kind of configuration, but (again), you could use a HashRouter as alternative.
r
For github pages it is a long story: https://github.com/isaacs/github/issues/408
d
@hfhbd I might be missing something but even with a hashrouter, if someone opens up say an incognito window and visits a subpage, you'll get a 404?
Whereas Kobweb will actually generate the site with all files in their expected places
r
No because the hash part of the URL is ignored by the server when serving up resources.
r
hash routing always opens index.html, it's not processed by the server
d
It's also possible, although I'm not 100% certain, that this will allow better SEO support, in case there are crawlers that run over text and don't run the javascript file.
👍 1
r
@David Herman My use case is a bit different than the static non-hash URL routing problem. A user creates an "entity" in my application. Normally this entity is rendered via Compose/Web, but dynamically I'd also like to create a static version of that for SEO reasons: something that loads extremely quickly and is easy to index by search engines. These SEO-friendly pages would essentially be entry-points to the main application. Is doing something like that possible? Can I use Kobweb via an API to generate these static pages?
d
Is compile time OK?
Will you know before you deploy?
r
Not really because these entities are created at runtime. I can always use Kotlin scripting or something to trigger the compiler at runtime though.
d
At the moment then I'm not sure, I don't think so
🆗 1
That sounds like server side rendering though? Except where you save the file on the server after you serve it?
r
It is server-side rendering, yes. Which compose/web doesn't really support. I know JW has done something in that area, but I recall him saying it wasn't easy and AFAIK he hasn't shared it.
So I was looking for work-arounds short of trying to implement it myself :-)
d
By the way the chat flew by really quickly before so I didn't get to say thanks for explaining the idea of hash URLs
although I do like URLs that look clean, whether that's a benefit or not may be a stylistic thing though
r
Its the "original" way of routing for SPAs, before people figured out how to make the URLs clean. I agree, I prefer them clean as well.
d
@rocketraman I'm going to ping you later (I have to run in a bit), would love to chat about your usecase 1:1
👍 1
m
Kinda offtopic but still related to rendering HTML: I wonder how hard would it be to run the application JS file with GraalJS, letting it render the page for you instead of spinning up an entire web browser. This would be useful for SSR that has dynamic content. I once played with this idea before, and while it could be possible, you would need to polyfill a lot of browser stuff (like the DOM). On my personal project what I ended up doing was checking if the browser User-Agent is a Crawler bot and, if it is, load the page using Playwright and output the rendered page to the Crawler. It works, but it is veeery slow compared to just not doing that and you use way more resources.
r
I've been looking at Playwright as well. It'll probably work for my use case if I cache its output. AIUI Google heavily penalizes pages that crawl slowly, so you're probably better off letting their JavaScript crawler index your page then having a slow response to their normal crawler.