Building howtall.is

December 7, 2024

Yet again, Joe provided the spark:

Bluesky post: Ok there's enough surprise at Justin's height that I feel we should get on the same page / Please report your height below / 6' even reporting for duty

I immediately knew I needed to build an app to let internet friends guess your height and find out just how much they were under- or over-estimating how tall you are. Justin Jackson's a great example: he gives off 6'1" energy (to me, anyhow) but he's actually 5'8". And I've seen him in person and I still thought he was taller!

How tall is...

I have some experience building viral voting apps - my largest picked up about 250,000 unique users - and the name of the game is simplification. Avoid inserts to your database unless you have to, cache as much as you can, make your GET requests as low impact as possible, keep things light and cheap. By Laravel standards, I went with a bare metal approach: a couple of controllers, server side rendered blade views, and a little bit of AlpineJS on the frontend. Guesses can be made by guests, reducing friction for users. I did make one tradeoff: since it's just for fun, and not business critical, it's easy to vote stuff and I didn't work hard on any de-duping or anti-abuse logic.

The Bluesky API

This project uses the Bluesky API a few ways:

OAuth for authentication

The Bluesky OAuth implementation is quite novel and honestly, hard to integrate. I hacked on this for fun with Chris Morrell and after 4 hours, we were still struggling. We eventually got a proof of concept working, but that's about when we discovered the revolution/laravel-bluesky package. That package handles OAuth and a Laravel Socialite integration to make it easy to authenticate users. Highly recommended.

Public API for user data

I wanted visitors to be able to guess on someone who hadn't even heard of howtall.is. To do this, I just needed a handle, avatar, and display name - fortunately those are all available on this endpoint. When a user provides a handle, I do a quick API lookup, cache it in my database, and show the profile.

Public API for autocompleting user search

There's a perfect endpoint for this: app.bsky.actor.searchActorsTypeahead. I whipped up a quick AlpineJS component to query that API and render an autocomplete UI.

Screenshot of howtall.is user search autocomplete interface

Sweet open graph images

Sample open graph image for Ben Holmen

Open Graph images are the images you see when you share a link on social media. They're a critical factor in making something viral because they make your links more unique and enticing. For this application I decided to create unique images for each user, including their Bluesky avatar in the image. I think this makes people more likely to share their own link, and more likely to engage with an image of someone they recognize.

Open graph images can be rendered a few ways - the most flexible and complex involves using something like Browsershot (or Browsershot on AWS Lambda) to render an entire webpage, take a screenshot, and save it. In my experience that takes about 3-5s per image and some finicky dependencies. For this project, that wasn't the right fit - I wanted to use the standard PHP library to create the image once and cache it. No dependencies, but not trivial.

To execute that lightweight, no-dependency approach, I created a base template image with a spot for an avatar. I then download their avatar, resize it to fit, crop to a circle with a transparent background, and copy that circle onto the base template. The image is saved to the disk so it only has to be rendered once, then returned to the user.

Laravel Cloud ☁️

Oh, and it's all deployed on an early release of Laravel Cloud! The kind people at Laravel Inc graciously let me take it for a spin and I only have great things to report. Everything demonstrated on stage at Laracon US 2024 just...works now. 10/10 experience!


Popular Posts

Recent Posts

View all