anze3db, to random
@anze3db@fosstodon.org avatar

One thing that I'm missing with HTMX and Django is proper error handling.

By default HTMX swallows any response that is not a 2xx, which might leave your users hanging on an endless loading state.

Does anyone have a good solution for this that can be reused between projects?

video/mp4

aral,
@aral@mastodon.ar.al avatar

Also, not immediately relevant to your current issue but something that might be worth considering for the future: using the htmx websocket extension, you can basically implement a streaming HTML approach (example using Kitten: https://ar.al/2024/03/08/streaming-html/) where you can just stream errors to the page as they happen.

(2/2)

aral, to SmallWeb
@aral@mastodon.ar.al avatar

The Evergreen Web section in Kitten’s¹ settings now has its own page too (and uses Kitten’s new Streaming HTML² workflow).

If you have the previous version of your site up somewhere, you can use the 404-to-307 technique³ to forward missing pages to your old site so as not to break the Web.

I’ll add local static archive support later.

¹ https://codeberg.org/kitten/app
² https://ar.al/2024/03/08/streaming-html/
³ https://4042307.org

#Kitten #SmallWeb #EvergreenWeb #StreamingHTML #web #dev #NodeJS #JavaScript

newcrafts, to random French
@newcrafts@mastodon.social avatar

Introducing the Small Web, where you own and control your space online. Join Aral Balkan in a live coding demo using Kitten, a Small Web server empowering everyday folks to craft their own corner of the internet. Let's reclaim the web for people, not profits!
Watch: https://buff.ly/497SHNg and join us at the Conference!

aral,
@aral@mastodon.ar.al avatar

@newcrafts And this was last year, Kitten has come a long way since then…

Check out the new Streaming HTML workflow:

https://ar.al/2024/03/08/streaming-html/

And how it made it possible to build Draw Together in less than 60 lines of code:

https://ar.al/2024/03/26/draw-together/

Wishing you a lovely conference this year :)

aral, to SmallWeb
@aral@mastodon.ar.al avatar

Just updated the video on my Streaming HTML article so it’s no longer using Vimeo’s video player (which has tracking) but a simple video tag.

https://ar.al/2024/03/08/streaming-html/

(Sorry it took a little while, it involves a bit more work – but not much more – than simply copying the embed code over.)

PS. Would anyone be interested in a little write-up of how to embed Vimeo videos without their player/tracking but still keeping the closed captions?

aral, to SmallWeb
@aral@mastodon.ar.al avatar

So given it’s Saturday night, I thought I’d have a little fun with Kitten and make a tiny collaborative drawing toy.

You have a 20×20 grid and only black and white to draw with and everyone shares the same canvas.

https://draw-together.small-web.org

Have fun + looking forward to seeing what we all, umm, draw together.

:kitten:💕

PS. It took about 60 lines of code.

View source: https://codeberg.org/aral/draw-together

aral,
@aral@mastodon.ar.al avatar

I’ve also updated the readme with instructions on how to run Draw Together yourself (you could have it up and running locally in under a minute by installing Kitten, cloning the repository, and running the kitten command) and links to where you can learn more about the Streaming HTML magic in Kitten that means that the whole app is ~60 lines of code :)

https://codeberg.org/aral/draw-together#draw-together

aral, to SmallWeb
@aral@mastodon.ar.al avatar

Minor Kitten¹ update: Even if your page routes now return nothing (e.g., null, undefined, empty string), a proper page will be rendered that includes the development-time WebSocket that powers hot reloads.

So the shortest valid page route is now:

export default () => ''  

And, more importantly, e.g.,

export default () => kitten.html`  
 <page css>  
`

Will also render.

:kitten:💕

¹ <https://codeberg.org/kitten/app>

#Kitten #SmallWeb #HTML #CSS #JavaScript #htmx #hypermedia #web #dev
aral,
@aral@mastodon.ar.al avatar

@lil5 Nope. It’s its own server + framework. The runtime is Node.js (which it downloads its own copy of during installation) and, while it will happily serve your static site from 1993 (ok, maybe not cgi-bin), the stuff you’re seeing in this example uses its Streaming HTML workflow based on htmx, WebSockets, and a little Kitten magic (https://ar.al/2024/03/08/streaming-html/) :)

aral, to SmallWeb
@aral@mastodon.ar.al avatar

🍞 Kitten toast, anyone?

A fifteen-second demo of how you can create a toast message in 42 lines of code¹ without writing any client-side JavaScript using Streaming HTML² in Kitten³.

Video:

https://vimeo.com/925828491

Source code:

https://codeberg.org/kitten/app/src/branch/main/examples/streaming-html/toast/index.page.js

Enjoy!

:kitten: 💕

¹ Almost half of which is CSS.
² https://ar.al/2024/03/08/streaming-html/
³ https://codeberg.org/kitten/app

aral,
@aral@mastodon.ar.al avatar

PS. Those 42 lines are all the source code.

That’s it.

No scaffolding. No npm create this-or-that.

  1. Create a folder called toast.
  2. Add those 42 lines of code to a file called index.page.js in that folder.
  3. Run kitten¹.

Now hit https://localhost in your browser and you will see the example running just like in the video in the first post.

:kitten: 💕

¹ https://codeberg.org/kitten/app

Kitten

aral,
@aral@mastodon.ar.al avatar

Update: I forgot to make the toast message div into an aria-live region so toast messages are read out when they arrive for people who use screen readers.

Now fixed.

Source code: https://codeberg.org/kitten/app/src/branch/main/examples/streaming-html/toast/index.page.js

Thanks to @hi_mayank for catching that one. Appreciate it!

:kitten: 💕

aral, to web
@aral@mastodon.ar.al avatar

Just released @small/state v3.0.2

🎉 Persistence is not futile! 🎉

Persist custom State objects in JSDB¹.

https://codeberg.org/small-tech/state

Just got it working in Domain² (a Kitten³ app). It’s such a sweet workflow. Store state keyed to session keys and use Streaming HTML⁴ to stream hypermedia interface updates.

:kitten: 💕

¹ https://codeberg.org/small-tech/jsdb
² https://codeberg.org/domain/app
³ https://codeberg.org/kitten/app
https://ar.al/2024/03/08/streaming-html/

SmallWeb

Screenshot of split terminal window showing, on top, a log of the state objects: Progress indicator state: RegistrationFormState { _state: 'CHECKING_AVAILABILITY', _states: { INITIAL: {}, CHECKING_AVAILABILITY: {}, AVAILABLE: {}, UNAVAILABLE: {}, ERROR: {} }, domain: 'small-web.org', application: { name: 'Place', source: 'https://codeberg.org/small-web/place.git' }, subdomain: '', customApplicationSource: '' } … RegistrationFormState { _state: 'AVAILABLE', _states: { INITIAL: {}, CHECKING_AVAILABILITY: {}, AVAILABLE: {}, UNAVAILABLE: {}, ERROR: {} }, On the button pane is a tail of JSDB database (append only JavaScript log) where the states are stored, keyed to session IDs: _['UB2WuGmK1ltayWBv4J_SlV_d']['registrationFormState'] = Object.create(typeof RegistrationFormState === 'function' ? RegistrationFormState.prototype : {}, Object.getOwnPropertyDescriptors({ '_state':
Screenshot of code. Highlighted area reads: page.on('subdomain', (/**
Screenshot of code. Highlighted area, which is after the one if the previous screenshot, towards the end of the file, reads: switch (true) { case (subdomain.trim() === ''): // Disallow queries comprised solely of whitespace. // (But no need to display an error, so we just set it back to the initial state.) state.set(state.states.INITIAL) break case (

aral, to SmallWeb
@aral@mastodon.ar.al avatar

Kitten update: session IDs now available in the request.session objects you get in your routes.

Kitten lets you persist arbitrary data in session objects to make it easy to work with sessions but you cannot store custom objects (instances of custom classes) as Kitten’s default database is not aware of custom classes in your application. Now, keyed to the session id, you can store custom objects in your app’s own database.

https://codeberg.org/kitten/app#sessions

:kitten: 💕

aral,
@aral@mastodon.ar.al avatar

(The use case for this is pretty neat: keep your interface state in custom state class instances persisted in session objects and, using the Streaming HTML workflow*, send back pieces of the interface that take those state objects as their only prop. Quite a neat separation of concerns and state is maintained only on the server in those objects.)

aral, (edited ) to SmallWeb
@aral@mastodon.ar.al avatar

New blog post: Streaming HTML

https://ar.al/2024/03/08/streaming-html/

Let me show you how easy it is to create a simple counter web app using the new Streaming HTML workflow in Kitten before peeling away the magic layer by layer so you learn how to make the same app using:

• HTMX & WebSockets
• Plain old JavaScript, and, finally,
• Without Kitten in pure Node.js.

Enjoy + let me know what you think.

:kitten: 💕

aral, (edited ) to SmallWeb
@aral@mastodon.ar.al avatar

Recorded the first video with my new setup last night, about Kitten’s new Streaming HTML workflow.

(And, unlike most quick demos, it doesn’t ignore accessibility.)

It’ll be part of a long blog post dissecting exactly how it works, step by step.

Here’s a little peek before that.

Let me know what you think :)

:kitten: 💕

https://vimeo.com/920601063

(You can install Kitten and play along: https://codeberg.org/kitten/app#getting-started)

aral, (edited ) to streaming
@aral@mastodon.ar.al avatar

I mean, I’m not saying you should stream CSS changes from the server every 300ms… just that you can if you want to ;P

(I’m playing around with the new/experimental Streaming HTML flow in Kitten* and testing its limits and trying to get a feel for how it wants to be used.)

aral, to SmallWeb
@aral@mastodon.ar.al avatar

I’m really enjoying the new Streaming HTML workflow in Kitten…

In this 15 second video, I cycle through the options in a selection box using the keyboard and the rest of the interface updates in response.

✨ There’s no custom client-side JavaScript making it happen. ✨

It’s all server side.

The changes stream to the client as HTML and are morphed into place via idiomorph.

So simple and maintainable.

💕

https://vimeo.com/908339606

aral,
@aral@mastodon.ar.al avatar

Right, is now integrated into and enjoys first-class support via the <page> tag like itself, the htmx extension, Alpine.js, and Water semantic library.

It’s auto-loaded for you if you expose onConnect() handlers in your pages when using the new workflow.

(You must still manually add htmx-swap-oob='morph' to elements you want to morph. I might add syntactic sugar for this later.)

¹ https://github.com/bigskysoftware/idiomorph/tree/main?tab=readme-ov-file#%EF%B8%8F-idiomorph

² https://codeberg.org/kitten/app

aral, to SmallWeb
@aral@mastodon.ar.al avatar

Very excited about the latest feature/workflow I’m adding to Kitten. I call it… 🥁

✨ Streaming HTML ✨

Implement back-end functionality and stream HTML updates to the client without writing any front-end JavaScript.

Just give your forms names and listen for them in an onConnect() handler you export from your page. Kitten handles everything else – setting up a WebSocket route for you, mapping triggers to events, etc. – thanks to Kitten + magic 🪄

aral,
@aral@mastodon.ar.al avatar

So the canonical example for any new web workflow appears to be a simple counter button.

Here’s one showing you the new Streaming HTML workflow in Kitten¹.

Note that the count is actually being persisted in the database (notice I turn the development server off and back on again mid demo).

What you see in the video is all the code there is in the project.

https://vimeo.com/907918005

¹ https://codeberg.org/kitten/app

aral,
@aral@mastodon.ar.al avatar

Right, this is now merged in main.

Please consider the Streaming HTML workflow very experimental for the time being (as all of Kitten is, really, but this more so).

There’s also still scant documentation but that will improve in the coming days. (I’ve added this demo to the readme.)

https://codeberg.org/kitten/app#to-whet-your-appetite

  • All
  • Subscribed
  • Moderated
  • Favorites
  • JUstTest
  • thenastyranch
  • DreamBathrooms
  • InstantRegret
  • magazineikmin
  • GTA5RPClips
  • khanakhh
  • Youngstown
  • Durango
  • slotface
  • rosin
  • ethstaker
  • kavyap
  • everett
  • provamag3
  • mdbf
  • osvaldo12
  • tacticalgear
  • modclub
  • cisconetworking
  • ngwrru68w68
  • Leos
  • cubers
  • tester
  • normalnudes
  • megavids
  • anitta
  • lostlight
  • All magazines