Media Asset Management in the Jamstack
Older Article
This article was published 6 years ago. Some information may be outdated or no longer applicable.
I recently got pulled into a discussion about media management in the Jamstack. I shared thoughts on best practices and available options for developers. This article captures the core of that conversation.
In the Jamstack ecosystem, there are two ways to manage images: through a static site generator, or through a (headless) CMS.
Both work. You could pick either for your next project. But they behave differently. Let’s look at how.
New to the Jamstack? There are many free introductory resources available online.
Managing images via a static site generator
With static site generators, we create templates that get populated during the build process. The result is a set of “static” HTML files. These files can reference images, and each generator handles images its own way.
Some generators have an “assets” folder with static files like images and icons. Generators like Gatsby can take those static assets and run them through plugins. For images, Gatsby uses a low-level image library called Sharp via the Gatsby Sharp Plugin.
Gatsby recently announced parallel image processing for their pipeline. They can now handle image processing as a separate, standalone process that doesn’t block static site generation.
Using a plugin like this is a good starting point for optimised images. But there are several drawbacks to the approach (which I’ll cover in a future post).
Other generators, like eleventy, need us to specify the “images” folder location explicitly. It copies the content over to the final build location.
So that’s one approach: store images locally, then move them to the “build” folder.
This strategy works well when you’ve got a limited number of images. But with a large number (especially if images need to be managed through a GUI), you’ll want something else.
Picture a hypothetical e-commerce platform. Each product could be a Markdown file with YAML frontmatter:
---
name: 'White T-Shirt'
price: 12.99
image: 'assets/images/white-t-shirt.jpg'
---
This product is made from the most environment-friendly material ...
Without a CMS, we need to name image files correctly and maintain them ourselves. That gets tedious fast, especially when products need multiple photos.
On the flip side, if we just need profile pictures for three employees, three photos is no big deal.
Another approach: bring in a CMS to manage content and images together.
Managing images using a CMS
Headless CMSes are thriving in the Jamstack ecosystem. For those unfamiliar with the term: a headless CMS decouples the presentation layer from the data layer. It lets us store and manage data (plus users and the other things you’d expect from a CMS), but it doesn’t dictate how the content gets consumed.
There are git-based and API-based headless CMSes. API-based ones expose HTTP endpoints to return data. Git-based ones manage content through markdown files and git.
Regardless of which type you choose, they share one thing: they let us manage and organise content, and (most importantly) they can provide an interface accessible to non-technical people.
Going back to the e-commerce example: we could set up a CMS where we manage products and their images through a single interface. Depending on the CMS, images might end up in a database or some other location. That’s transparent to us. What matters is that we can manage and retrieve them when needed.
Note that out-of-the-box behaviour varies between CMSes. Netlify CMS still manages images on the filesystem (using git), while Strapi creates an entry in its underlying database (SQL or NoSQL). Both Strapi and NetlifyCMS have ways to upload images to different providers, extending their media management capabilities and giving users a better experience.
The morale of the story
So which is better: managing images via a static site generator or a headless CMS? There’s no clean answer. You need to evaluate which option fits your project. Both are valid, and each suits slightly different use cases.