Shields: Announcing the raster server

Created on 7 Jul 2019  ·  9Comments  ·  Source: badges/shields

Shields has changed the way it presents raster badges – i.e. badges in PNG, GIF, and JPG format.

https://img.shields.io/v/npm/express.png
↪️https://raster.shields.io/v/npm/express.png

What has changed?

  • img.shields.io renders only SVG and JSON badges.
  • Previously it also supported PNG, GIF, and JPG.
  • PNG badges are rasterized downstream at raster.shields.io

    • For backward compatibility, the PNG URLs will 301 redirect to raster.shields.io

  • Support for GIF and JPG has been removed.

Note: The legacy raster static badge route, https://img.shields.io/label/message.png has been discontinued. (#3659) URLs of that form should be updated to use one of the modern routes:

Why was this changed?

Shields has always been about SVG badges first, because they look better and perform better.

PNG badges are a fringe but meaningful use case for badges in emails, and services like Slack which don’t support SVG.

Moving rasterization off-board simplifies the responsibilities of the badge server and hardens the server, as it prevents someone from overloading the server with raster requests. (Each raster request used a subprocess, making them much more expensive than SVG badges.)

GIF and JPG were removed because, on a monthly basis, these were barely touched.

Read more: #3112

How does it work?

Notes

  • If you self-host a copy of Shields and need to support raster badges, you will need to host your own copy of the raster server. You can do that inexpensively on Zeit Now or on your own hardware.

    • If you've gotten set this up, we'd welcome better documentation! (#3648)

  • The raster server will always return PNG, and will work even if you don't replace .svg with .png in the URL (e.g. https://raster.shields.io/v/npm/express.svg)

Acknowledgements

Thanks to the Shields maintainer team, to @styfle whose post about Serverless Chrome on Now 2.0 helped me get this off the ground, and to @neocotic for convert-svg.

Feedback

Your feedback on the new feature is much appreciated! Feel free to comment in this issue with feedback or questions, or in the #support room in Discord.

Related issues

  • [x] #3631
  • [x] #3644
  • [ ] #3648
  • [ ] #3647
core documentation operations self-hosting

Most helpful comment

Thanks for the acknowledgement! Great to see my little tool being used. I realised that I haven't touched it in a little while so might go back and see how it's faring. As a user and fan of shields.io, I was wondering if there's anything that you'd like to see specifically.

All 9 comments

Thanks for taking on this piece of work Paul, it's nice to have separated raster functionality out!

Thanks for the acknowledgement! Great to see my little tool being used. I realised that I haven't touched it in a little while so might go back and see how it's faring. As a user and fan of shields.io, I was wondering if there's anything that you'd like to see specifically.

Thanks for asking @neocotic!

I guess there are two things that might be useful:

  1. I'd love to support retina png's… though I actually have no idea what is involved in that!
  2. Support for puppeteer-core would be nice in Shields' case, and might be useful for other users as well. I think this would simplify the install. For us, installing puppeteer on Now means passing an env var that prevents Chromium from being downloaded. This wouldn't be necessary with puppeter-core (which is "bring your own Chromium").

@neocotic To add a little more context about why puppeteer-core would be useful: I'd like to publish the web function on npm, and make the app a tiny page that includes just the web function. I've had trouble doing that, in part because I can't just declare the dependencies I want. The env var, for example, must be set when npm install runs. If I could just declare the dependencies, I'd make it easier for people to host their own svg-to-image-proxy without needing to create their own fork.

I noticed that the raster example, badge/label-message-color, sets a header cache-control: max-age=86400 but this does not take advantage of the CDN Edge.

Consider adding s-maxage like the caching docs mention:

cache-control: max-age=86400, s-maxage=86400, public

You could even add immutable for static badges that you know will never change.

Thanks so much! That could help a lot here! We've tried to avoid immutable because of changes in the template and server bugs, but setting fairly long timeouts should have a pretty similar effect.

No problem!

Also note that deploying will purge the CDN Edge cache https://vercel.com/docs/v2/edge-network/caching#cache-invalidation

@paulmelnikow - do you have a handle on how the headers are set/forwarded with the raster proxy? I know @calebcartwright is following up on https://github.com/badges/shields/issues/3647#issuecomment-621582157 but if we can cut our costs in the meantime with a header, that seems like its worth following up.

There's a short list of headers that are copied from the upstream svg response: https://github.com/badges/svg-to-image-proxy/blob/aa3486603f6e67295d1857351a1de8b47732257e/index.js#L20-L25

So the place to make this change is probably in Shields:

https://github.com/badges/shields/blob/7af965113b7c202abbb57ce6023d754ed1cf2018/core/base-service/cache-headers.js#L72

I'm not 100% sure we want public in there. We should think about whether that's a problem for self-hosting.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

rominf picture rominf  ·  3Comments

paulmelnikow picture paulmelnikow  ·  3Comments

calebcartwright picture calebcartwright  ·  3Comments

AlexWayfer picture AlexWayfer  ·  3Comments

PyvesB picture PyvesB  ·  3Comments