Steve.ly

Steve.ly

2008 – PresentSee live
Steve on X

My website. Such recursion. It's where my projects, résumé and references live, and since I left the UK in 2016 to travel and work remotely, it's also where ten years of that travel lives: every trip, flight, stay, photo and review, on a globe.

The first version went up in 2008, and this is the fifth. It's Laravel, Tailwind and Alpine, rebuilt in 2020, and has had nearly 450 commits since, a big chunk of them in 2026.

Steve.ly

Ten years of travel, on a globe

Trips come from Nomads, where I log them anyway, over its MCP server. Trips in the same country are grouped into stops, and posts and photos are attached to the stop they belong to. Every edit I make on Nomads flows through the next morning, and things that no longer match drop off rather than being deleted, so they come back if the trip does.

There are pages for every year, continent, country, region and place, a globe with the routes between them, and the map data to download as KML or GeoJSON.

Travels on steve.ly, with a globe of South America
Travels, with the globe

Flights, from the confirmation emails

Flights are read out of booking emails, and the e-tickets and invoices attached to them, from Kiwi, Gotogate and the airlines themselves. Layovers are joined into one journey, and airports in the same city count as one. The plane comes from the ticket where it says, or from the airline's fleet where it doesn't, and hovering a plane, airport or airline shows a card with its photo and scores.

Places, and where I stayed

Stays come from Airbnb, Booking.com and Agoda confirmations, with each listing's photo and rating, copied before the links to them expire. Photos come from Instagram exports and from Google Photos, read straight out of Takeout archives in Google Drive: a small reader fetches just the file it needs from a multi-gigabyte zip with range requests, without downloading the archive. Posts, check-ins and reviews fill in the rest, with repeat visits to a place counted by matching nearby check-ins.

Rio de Janeiro on steve.ly
A place page, with its trips, stays and posts

Share cards that move

Every page has its own share card, rendered by a Cloudflare Worker I wrote and open-sourced, which runs a headless browser and stores the result in R2. It can emulate dark mode and reduced motion, and record video too, so sharing the travels page posts a ten-second clip scrolling through the last three years, in dark mode.

Projects, skills and the people behind them

Projects, skills, employers and references are all connected, so every skill and employer gets a page at its own short URL, like steve.ly/laravel. Project write-ups like this one are built from blocks in the admin, and the résumé is drawn from the same data, with print styles that summarize older roles and drop the links on paper.

Projects on steve.ly
Projects
The résumé on steve.ly
The résumé

Small things, done properly

  • ⌘K search across projects, skills, employers, countries and places, which also works from the browser's address bar and jumps straight to an exact match

  • Dark mode and reduced motion that follow your system, from the first paint

  • Structured data on every page, and a sitemap of every place

  • Public pages that set no cookies, so Cloudflare can cache them for a month

  • A Worker that serves photos and video from R2, range requests and all

  • Asteroids, if you know the Konami code

Under the hood

  • Laravel 13 and PHP 8.4, Blade, Tailwind 4 and Alpine, with globe.gl and MapLibre

  • A Filament admin, which replaced Nova in 2026

  • Pest tests for the imports, the zip reader, the structured data and every public page, with fixtures in place of real data

  • CI and deploys on self-hosted GitHub Actions runners, and weekly pull requests for dependency updates

Five versions

  • 2008: XHTML Strict and jQuery, with a portfolio written in XML and styled with XSL, from my university days.

  • 2010: HTML5, a blog, a portfolio and a lab, with a Markdown admin, from my time at Wired Media.

  • 2013: responsive, with a CV page, while I was at Simpleweb.

  • 2016: a résumé and a sortable admin.

  • 2020: this one, on Laravel, with share cards from day one.