In late August I gave this site a small upgrade: each project card on the home page got a photo, and I built myself a little admin editor so I could upload and swap those photos without touching any files. I uploaded the first photo, the editor said it saved, I refreshed the page โ and got a broken image icon.
Then I checked the other cards. Every photo on the site was broken. Not one of them loaded.
If you can't code, this is the kind of bug that makes you want to give up, because every
individual piece looks fine. The upload succeeded. The file really existed on the server โ
I could see it. The page really was asking for the image โ I could see the request in the
browser's developer tools, returning 404 Not Found for a file I knew existed.
The browser and the server were both telling the truth. They were just talking about different places.
Hatch & Build isn't one server pretending to be one website โ it's two. The page you're
reading lives at hatchandbuild.com, which is a plain static site. But the drawing
wall and the project data live on a second server at drawing.hatchandbuild.com,
and that's also where my new upload feature saved the photos.
When a photo was uploaded, the server recorded its location as a relative path โ
something like /hub-images/project-1.jpg. No domain in front, just the path.
And here's the rule I had never learned: a path without a domain is not an address,
it's a fragment of one. The browser completes it using whatever domain the current
page is on.
So the photo was sitting at drawing.hatchandbuild.com/hub-images/project-1.jpg,
but the page displaying it was on hatchandbuild.com โ so the browser politely
asked hatchandbuild.com/hub-images/project-1.jpg, a place where no photo has ever
existed. Hence: 404, for a file that absolutely existed. Both servers were right. I had simply
never told the browser which one to ask.
Once I understood the problem, the fix was almost insultingly small: before putting an image
path into the page, check whether it starts with /hub-images/, and if so, glue the
API server's full address onto the front. Paths that are already complete addresses get left
alone. Three lines of code, one afternoon of confusion.
I also left a comment in the code explaining why those three lines exist โ because the version of me who finds this code in six months will not remember, and will be very tempted to "clean it up."
This is what building without a background actually looks like. Not smooth demos โ a broken image icon, an evening of asking "but the file is right there," and then one small rule about how the web works that I'll never forget again.
More of these as they happen โ and they will happen. Follow along on Instagram or check the build log.