Skip to content

Use immutable hashed urls for /play/#/cover and /play/#/full_cover - #489

Open
dfabulich wants to merge 1 commit into
iftechfoundation:mainfrom
dfabulich:fix-cover-art-cache
Open

dfabulich wants to merge 1 commit into
iftechfoundation:mainfrom
dfabulich:fix-cover-art-cache

Conversation

@dfabulich

Copy link
Copy Markdown
Contributor

Before this change, ballot image URLs would look like:

  • /play/100/cover
  • /play/100/full_cover

And they would have Cache-Control: max-age=86400, 24 hour caching. If an author tried to change their cover image, it would not take effect for end users for up to 24 hours.

Now, ballot image URLs include the hash of their content:

  • /play/100/cover/6f3258d40362b2c5
  • /play/100/full_cover/184051209a39ecc8

These URLs have Cache-Control: public, max-age=31536000, immutable, i.e. far-future immutable caching.

The hash is stored in geometry.txt for the web cover, and in hash.txt for the full cover.

The ballot reads the stored hashes to generate HTML like this:

<a href="/play/100/full_cover/184051209a39ecc8">
  <img src="/play/100/cover/6f3258d40362b2c5">
</a>

When the author uploads a new image, the ballot HTML (which is never cached) instantly uses new URLs for the image, making the latest cover art immediately visible to judges. Judges never need to redownload images that are already cached.

Before this change, ballot image URLs would look like:

* `/play/100/cover`
* `/play/100/full_cover`

And they would have `Cache-Control: max-age=86400`, 24 hour caching. If an author tried to change their cover image, it would not take effect for end users for up to 24 hours.

Now, ballot image URLs include the hash of their content:

* `/play/100/cover/6f3258d40362b2c5`
* `/play/100/full_cover/184051209a39ecc8`

These URLs have `Cache-Control: public, max-age=31536000, immutable`, i.e. far-future immutable caching.

The hash is stored in `geometry.txt` for the web cover, and in `hash.txt` for the full cover.

The ballot reads the stored hashes to generate HTML like this:

```
<a href="/play/100/full_cover/184051209a39ecc8">
  <img src="/play/100/cover/6f3258d40362b2c5">
</a>
```

When the author uploads a new image, the ballot HTML (which is never cached) instantly uses new URLs for the image, making the latest cover art immediately visible to judges. Judges never need to redownload images that are already cached.
@dfabulich

Copy link
Copy Markdown
Contributor Author

If we use Cloudflare, Cloudflare will cache these images at the edge, so users will never have to download images directly from sword. This should significantly reduce the load on sword, hopefully improving site stability.

@dfabulich dfabulich mentioned this pull request Sep 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant