Jeremy Keith's Blog, page 8

October 20, 2024

Archives

Speaking of serendipity, not long after I wrote about making a static archive of The Session for people to download and share, I came across a piece by Alex Chan about using static websites for tiny archives.

The use-case is slightly different���this is about personal archives, like paperwork, screenshots, and bookmarks. But we both came up with the same process:

I���m deliberately going low-scale, low-tech. There���s no web server, no build system, no dependencies, and no JavaScript frameworks.


And we share the same hope:

Because this system has no moving parts, and it���s just files on a disk, I hope it will last a long time.


You should read the whole thing, where Alex describes all the other approaches they took before settling on plain ol��� HTML files in a folder:

HTML is low maintenance, it���s flexible, and it���s not going anywhere. It���s the foundation of the entire web, and pretty much every modern computer has a web browser that can render HTML pages. These files will be usable for a very long time ��� probably decades, if not more.

I���m enjoying this approach, so I���m going to keep using it. What I particularly like is that the maintenance burden has been essentially zero ��� once I set up the initial site structure, I haven���t had to do anything to keep it working.


They also talk about digital preservation:

I���d love to see static websites get more use as a preservation tool.


I concur! And it���s particularly interesting for Alex to be making this observation in the context of working with the Flickr foundation. That���s where they���re experimenting with the concept of a data lifeboat

What should we do when a digital service sinks?


This is something that George spoke about at the final dConstruct in 2022. You can listen to the talk on the dConstruct archive.

 •  0 comments  •  flag
Share on Twitter
Published on October 20, 2024 06:15

Feed reading

I described using my feed reader like this:

I would hate if catching up on RSS feeds felt like catching up on email.


Instead it���s like this:

When I open my RSS reader to catch up on the feeds I���m subscribed to, it doesn���t feel like opening my email client. It feels more like opening a book.


It also feels different to social media. Like Lucy Bellwood says:

I have a richer picture of the group of people in my feed reader than I did of the people I regularly interacted with on social media platforms like Instagram.


There���s also the blessed lack of any algorithm:

Because blogs are much quieter than social media, there���s also the ability to switch off that awareness that Someone Is Always Watching.


Cory Doctorow has been praising the merits of RSS:

This conduit is anti-lock-in, it works for nearly the whole internet. It is surveillance-resistant, far more accessible than the web or any mobile app interface.


Like Lucy, he emphasises the lack of algorithm:

By default, you’ll get everything as it appears, in reverse-chronological order.

Does that remind you of anything? Right: this is how social media used to work, before it was enshittified. You can single-handedly disenshittify your experience of virtually the entire web, just by switching to RSS, traveling back in time to the days when Facebook and Twitter were more interested in showing you the things you asked to see, rather than the ads and boosted content someone else would pay to cram into your eyeballs.


The only algorithm at work in my feed reader���or on Mastodon���is good old-fashioned serendipity, when posts just happened to rhyme or resonate. Like this morning, when I read this from Alice:

There is no better feeling than walking along, lost in my own thoughts, and feeling a small hand slip into mine. There you are. Here I am. I love you, you silly goose.


And then I read this from Denise

I pass a mother and daughter, holding hands. The little girl is wearing a sequinned covered jacket. She looks up at her mother who says ������And the sun���s going to come out and you���re just going to shine and shine and shine.���


 •  0 comments  •  flag
Share on Twitter
Published on October 20, 2024 05:57

October 16, 2024

content-visibility in Safari

Earlier this year I wrote about some performance improvements to The Session using the content-visibility property in CSS.

If you say content-visibility: auto you���re telling the browser not to bother calculating the layout and paint for an element until it needs to. But you need to combine it with the contain-intrinsic-block-size property so that the browser knows how much space to leave for the element.

I mentioned the browser support:

Right now content-visibility is only supported in Chrome and Edge. But that���s okay. This is a progressive enhancement. Adding this CSS has no detrimental effect on the browsers that don���t understand it (and when they do ship support for it, it���ll just start working).


Well, that���s happened! Safari 18 supports content-visibility. I didn���t have to do a thing and it just started working.

But ���I think I���ve discovered a little bug in Safari���s implementation.

(I say I think it���s a bug with the browser because, like Jim, I���ve made the mistake in the past of thinking I had discovered a browser bug when in fact it was something caused by a browser extension. And when I say ���in the past���, I mean yesterday.)

So here���s the issue: if you apply content-visibility: auto to an element that contains an SVG, and that SVG contains a text element, then Safari never paints that text to the screen.

To see an example, take a look at the fourth setting of Cooley���s reel on The Session archive. There���s a text element with the word ���slide��� (actually the text is inside a tspan element inside a text element). On Safari, that text never shows up.

I���m using a link to the archive of The Session I created recently rather than the live site because on the live site I���ve removed the content-visibility declaration for Safari until this bug gets resolved.

I���ve also created a reduced test case on Codepen. The only HTML is the element containing the SVGs. The only CSS���apart from the content-visibility stuff���is just a little declaration to push the content below the viewport so you have to scroll it into view (which is when the bug happens).

I���ve filed a bug report. I know it���s a fairly niche situation, but there are some other issues with Safari���s implementation of content-visibility so it���s possible that they���re all related.

 •  0 comments  •  flag
Share on Twitter
Published on October 16, 2024 06:17

Docks and home screens

Back in June I documented a bug on macOS in how Spaces (or whatever they call they���re desktop management thingy now) works with websites added to the dock.

I���m happy to report that after upgrading to Sequoia, the latest version of macOS, the bug has been fixed! Excellent!

Not only that, but there���s another really great little improvement���

Let���s say you���ve installed a website like The Session by adding it to the dock. Now let���s say you get an email in Apple Mail that includes a link to something on The Session. It used to be that clicking on that link would open it in your default web browser. But now clicking on that link opens it in the installed web app!

It���s a lovely little enhancement that makes the installed website truly feel like a native app.

Websites in the dock also support the badging API, which is really nice!

Like I said at the time:

I wonder if there���s much point using wrappers like Electron any more? I feel like they were mostly aiming to get that parity with native apps in having a standalone application launched from the dock.

Now all you need is a website.


The biggest issue remains discovery. Unless you already know that it���s possible to add a website to the dock, you���re unlikely to find out about it. That���s why I���ve got a page with installation instructions on The Session.

Still, the discovery possibilities on Apples���s desktop devices are waaaaay better than on Apple���s mobile devices.

Apple are doing such great work on their desktop operating system to make websites first-class citizens. Meanwhile, they���re doing less than nothing on their mobile operating system. For a while there, they literally planned to break all websites added to the homescreen. Fortunately they were forced to back down.

But it���s still so sad to see how Apple are doing everything in their power to prevent people from finding out that you can add websites to your homescreen���despite (or perhaps because of) the fact that push notifications on iOS only work if the website has been added to the home screen!

So while I���m really happy to see the great work being done on installing websites for desktop computers, I���m remain disgusted by what���s happening on mobile:

At this point I���ve pretty much given up on Apple ever doing anything about this pathetic situation.


 •  0 comments  •  flag
Share on Twitter
Published on October 16, 2024 02:33

October 14, 2024

Train coding

When I went up to London for the State of the Browser conference last month, I shared the train journey with Remy.

I always like getting together with Remy. We usually end up discussing sci-fi books we���re reading, commiserating with one another about conference-organising, discussing the minutiae of browser APIs, or talking about the big-picture vision of the World Wide Web.

On this train ride we ended up talking about the march of time and how death comes for us all ���and our websites.

Take The Session, for example. It���s been running for two and a half decades in one form or another. I plan to keep it running for many more decades to come. But I���m the weak link in that plan.

If I get hit by a bus tomorrow, The Session will keep running. The hosting is paid up for a while. The domain name is registered for as long as possible. But inevitably things will need to be updated. Even if no new features get added to the site, someone���s got to install updates to keep the underlying software safe and secure.

Remy and I discussed the long-term prospects for widening out the admin work to more people. But we also discussed smaller steps I could take in the meantime.

Like, there���s the actual content of the website. Now, I currently share exports from the database every week in JSON, CSV, and SQLite. That���s good. But you need to be tech nerd to do anything useful with that data.

The more I talked about it with Remy, the more I realised that HTML would be the most useful format for the most people.

There���s a cute acronym in the world of digital preservation: LOCKSS. Lots Of Copies Keep Stuff Safe. If there were multiple copies of The Session���s content out there in the world, then I���d have a nice little insurance policy against some future catastrophe befalling the live site.

With the seed of the idea planted in my head, I waited until I had some time to dive in and see if this was doable.

Fortunately I had plenty of opportunity to do just that on some other train rides. When I was in Spain and France recently, I spent hours and hours on trains. For some reason, I find train journeys very conducive to coding, especially if you don���t need an internet connection.

By the time I was back home, the code was done. Here���s the result:

The Session archive: a static copy of the content on thesession.org.

If you want to grab a copy for yourself, go ahead and download this .zip file. Be warned that it���s quite large! The .zip file is over two gigabytes in size and the unzipped collection of web pages is almost ten gigabytes. I plan to update the content every week or so.

I���ve put a copy up on Netlify and I���m serving it from the subdomain archive.thesession.org if you want to check out the results without downloading the whole thing.

Because this is a collection of static files, there���s no search. But you can use your browser���s ���Find in Page��� feature to search within the (very long) index pages of each section of the site.

You don���t need to a web server to click around between the pages: they should all work straight from your file system. Double-clicking any HTML file should give a starting point.

I wanted to reduce the dependencies on each page to as close to zero as I could. All the CSS is embedded in the the page. Likewise with most of the JavaScript (you���ll still need an internet connection to get audio playback and dynamic maps). This keeps the individual pages nice and self-contained. That means they can be shared around (as an email attachment, for example).

I���ve shared this project with the community on The Session and people are into it. If nothing else, it could be handy to have an offline copy of the site���s content on your hard drive for those situations when you can���t access the site itself.

 •  0 comments  •  flag
Share on Twitter
Published on October 14, 2024 07:50

October 11, 2024

Travels in Europe

One of the perks of speaking at conferences is that I get to travel to new and interesting places. I���d say that most of my travel over the past couple of decades was thanks to conferences. Recently though, I���ve been going places for non-work related reasons.

A couple of weeks ago I was in Spain, making my way to the beautiful medieval town of C��ceres for a traditional Irish music festival there. This was the second year that Jessica have been.

It���s kind of perfect. Not only is it a beautiful location���the stand-in for King���s Landing in House Of The Dragon���but there are non-stop sessions late into night, often outdoors. And of course the food is great.

A flute player and a fiddle player have their backs to us; between them we can see a woman playing fiddle on the other side of the table. A group of musicians playing bodhr��n, fiddle, concertina and flute playing at a table outside a bar. A hand holding a fiddle in front of a young woman playing fiddle and another woman playing tin whistle. Loads of musicians playing around a table in a medieval courtyard.

It���s not easy to get to though. Last year we flew into Madrid and then took the train to C��ceres the next day. This year we did it slightly differently and flew into Seville instead. Then we took the four-hour train journey the next day. After the festival, we did it all in reverse.

That meant we had two evenings in Seville to sample its many tapas. On our last night in Seville, we had local guides. Blogger Dirk Hesse and his parter took us to all the best places. Dirk had seen that I was going to be in town and very kindly got in touch with an offer to meet up. I���m very glad we took him up on the offer!

Going to Spain in mid September felt like getting a last blast of Summer sun before returning to Autumn in England. The only downside was that the trip involved flying. But we���ve been on one more journey since then and that was done the civilised way, by train.

Jessica went to a translator���s conference in Strasbourg. I tagged along. We got the train from Brighton straight to Saint Pancras, where we got the Eurostar to Paris. From there it was a super fast connection straight to Strasbourg.

While Jessica was at her event all day, I was swanning around the beautiful streets, sampling the local wine and taking plenty of time to admire the details of Strasbourg���s awesome cathedral.

Looking up at the intricately detailed carvings on the main door of a cathedral. A cathedral door surrounded by intricate carvings of statues. Looking down the aisle of a cathedral at a magnificent rose window flanked by towering columns. An astronomical clock in a cathedral with vertical layers of circular mechanisms piled up in a tower.
 •  0 comments  •  flag
Share on Twitter
Published on October 11, 2024 03:29

October 10, 2024

Mismatch

This seems to be the attitude of many of my fellow nerds���designers and developers���when presented with tools based on large language models that produce dubious outputs based on the unethical harvesting of other people���s work and requiring staggering amounts of energy to run:

This is the future! I need to start using these tools now, even if they���re flawed, because otherwise I���ll be left behind. They���ll only get better. It���s inevitable.


Whereas this seems to be the attitude of those same designers and developers when faced with stable browser features that can be safely used today without frameworks or libraries:

I���m sceptical.


 •  0 comments  •  flag
Share on Twitter
Published on October 10, 2024 01:35

September 30, 2024

Preventing automated sign-ups

The Session goes through periods of getting spammed with automated sign-ups. I���m not sure why. It���s not like they do anything with the accounts. They���re just created and then they sit there (until I delete them).

In the past I���ve dealt with them in an ad-hoc way. If the sign-ups were all coming from the same IP addresses, I could block them. If the sign-ups showed some pattern in the usernames or emails, I could use that to block them.

Recently though, there was a spate of sign-ups that didn���t have any patterns, all coming from different IP addresses.

I decided it was time to knuckle down and figure out a way to prevent automated sign-ups.

I knew what I didn���t want to do. I didn���t want to put any obstacles in the way of genuine sign-ups. There���d be no CAPTCHAs or other ���prove you���re a human��� shite. That���s the airport security model: inconvenience everyone to stop a tiny number of bad actors.

The first step I took was the bare minimum. I added two form fields���called ���wheat��� and ���chaff������that are randomly generated every time the sign-up form is loaded. There���s a connection between those two fields that I can check on the server.

Here���s how I���m generating the fields in PHP:

$saltstring = 'A string known only to me.';$wheat = base64_encode(openssl_random_pseudo_bytes(16));$chaff = password_hash($saltstring.$wheat, PASSWORD_BCRYPT);

See how the fields are generated from a combination of random bytes and a string of characters never revealed on the client? To keep it from goint stale, this string���the salt���includes something related to the current date.

Now when the form is submitted, I can check to see if the relationship holds true:

if (!password_verify($saltstring.$_POST['wheat'], $_POST['chaff'])) { // Spammer!}

That���s just the first line of defence. After thinking about it for a while, I came to conclusion that it wasn���t enough to just generate some random form field values; I needed to generate random form field names.

Previously, the names for the form fields were easily-guessable: ���username���, ���password���, ���email���. What I needed to do was generate unique form field names every time the sign-up page was loaded.

First of all, I create a one-time password:

$otp = base64_encode(openssl_random_pseudo_bytes(16));

Now I generate form field names by hashing that random value with known strings (���username���, ���password���, ���email���) together with a salt string known only to me.

$otp_hashed_for_username = md5($saltstring.'username'.$otp);$otp_hashed_for_password = md5($saltstring.'password'.$otp);$otp_hashed_for_email = md5($saltstring.'email'.$otp);

Those are all used for form field names on the client, like this:

(Remember, the name���or the ID���of the form field makes no difference to semantics or accessibility; the accessible name is derived from the associated label element.)

The one-time password also becomes a form field on the client:

When the form is submitted, I use the value of that form field along with the salt string to recreate the field names:

$otp_hashed_for_username = md5($saltstring.'username'.$_POST['otp']);$otp_hashed_for_password = md5($saltstring.'password'.$_POST['otp']);$otp_hashed_for_email = md5($saltstring.'email'.$_POST['otp']);

If those form fields don���t exist, the sign-up is rejected.

As an added extra, I leave honeypot hidden forms named ���username���, ���password���, and ���email���. If any of those fields are filled out, the sign-up is rejected.

I put that code live and the automated sign-ups stopped straight away.

It���s not entirely foolproof. It would be possible to create an automated sign-up system that grabs the names of the form fields from the sign-up form each time. But this puts enough friction in the way to make automated sign-ups a pain.

You can view source on the sign-up page to see what the form fields are like.

I used the same technique on the contact page to prevent automated spam there too.

 •  0 comments  •  flag
Share on Twitter
Published on September 30, 2024 08:57

September 26, 2024

The datalist element on iOS

The datalist element is good. It was a bit bumpy there for a while, but browser implementations have improved over time. Now it���s by far the simplest and most robust way to create an autocompleting combobox widget.

Hook up an input element with a datalist element using the list and id attributes and you���re done. You can even use a bit of Ajax to dynamically update the option elements inside the datalist in response to the user���s input. The browser takes care of all the interaction. If you try to roll your own combobox implementation, it���s almost certainly going to involve a lot of JavaScript and still probably won���t account for all use cases.

Safari on iOS���and therefore all browsers on iOS���didn���t support datalist for quite a while. But once it finally shipped, it worked really nicely. The options showed up just like automplete suggestions above the keyboard.

But that broke a while back.

The suggestions still appeared, but if you tapped on one of them, nothing happened. The input element didn���t get updated. You had to tap on a little downward arrow inside the input in order to see the list of options.

That was really frustrating for anybody on iOS using The Session. By far the most common task on the site is searching for a tune, something that���s greatly (progressively) enhanced with a dynamically-updating datalist.

I just updated to iOS 18 specifically to see if this bug has been fixed, and it has:

Fixed updating the input value when selecting an option from a datalist element.


Hallelujah!

But now there���s some additional behaviour that���s a little weird.

As well as showing the options in the autocomplete list above the keyboard, Safari on iOS���and therefore all browsers on iOS���also pops up the options as a list (as if you had tapped on that downward arrow). If the list is more than a few options long, it completely obscures the input element you���re typing into!

I���m not sure if this is a bug or if it���s the intended behaviour. It feels like a bug, but I don���t know if I should file something.

For now, I���ve updated the datalist elements on The Session to only ever hold three option elements in order to minimise the problem. Seeing as the autosuggest list above the keyboard only ever shows a maximum of three suggestions anyway, this feels like a reasonable compromise.

 •  0 comments  •  flag
Share on Twitter
Published on September 26, 2024 08:16

September 17, 2024

Last Minute

I went along to this year���s State Of The Browser conference on Saturday. It was great!

Technically I wasn���t just an attendee. I was on the substitution bench. Dave asked if I���d be able to jump in and give my talk on declarative design should any of the speakers have to drop out. ���No problem!���, I said. If everything went according to plan, I wouldn���t have to do anything. And if someone did have to pull out, I���d be the hero that sweeps in to save the day. Win-win.

As it turned out, everything went smoothly. All the speakers delivered their talks impeccably and the vibes were good.

Dave very kindly gave shout-outs to lots of other web conferences. Quite a few of the organisers were in the audience too. That offered me a nice opportunity to catch up with some of them, swap notes, and commiserate on how tough it is running an event these days.

Believe me, it���s tough.

Something that I confirmed that other conference organisers are also experiencing is last-minute ticket sales. This is something that happened with UX London this year. For most of the year, ticket sales were trickling along. Then in the last few weeks before the event we sold more tickets than we had sold in the six months previously.

Don���t get me wrong: I���m very happy we sold those tickets. But it was a very stressful few months before that. It felt like playing poker, holding on in the belief that those ticket sales would materialise.

Lots of other conferences are experiencing this. Front Conference had to cancel this year���s event because of the lack of ticket sales in advance. I know for a fact that some upcoming events are feeling the same squeeze.

When I was in Ireland I had a chat with a friend of mine who works at the Everyman Theatre in Cork. They���re experiencing something similar. So maybe it���s not related to the tech industry specifically.

Anyway, all that is to say that I echo Sophie���s entreaty: you should go to conferences. And buy your tickets early.

Soon I���ll be gearing up to start curating the line up for next year���s UX London (I���m very proud of this year���s event and it���s going to be tough to top it). I hope I won���t have to deal with the stress of late ticket sales, but I���m mentally preparing for it.

 •  0 comments  •  flag
Share on Twitter
Published on September 17, 2024 08:55

Jeremy Keith's Blog

Jeremy Keith
Jeremy Keith isn't a Goodreads Author (yet), but they do have a blog, so here are some recent posts imported from their feed.
Follow Jeremy Keith's blog with rss.