Jekyll doesn’t do components? Liar!

Katie - Feb 23 '22 - - Dev Community

Hot take: anyone who tells you that Jekyll doesn’t support component-based design, and that you need a React- or Vue-based static site generator, is wrong.

  1. Any basic fragment-of-HTML “component” you can define with JSX in a file and then cross-reference as <MyComponent key="value" />, you can just as easily define with Liquid in a file and cross-reference in Jekyll as {% include MyComponent.html key=value %}.
  2. Any basic fragment-of-HTML “layout” you can define with JSX in a file and then cross-reference as <MyLayout>Hello, world</MyLayout>, you can just as easily define with Liquid in a file and then cross-reference in the front matter of a Jekyll template as layout: MyLayout.

Example

Remember my “what you see is what you get” (“WYSIWYG”) componentized Squarespace-style “site builder” I learned Gatsby so I could build last year?

I didn’t actually need Gatsby – here’s the source code in Jekyll, and ta-da, live site.

Screenshot of a basic componentized site, before and after editing

Drag-and-drop

Need to see with your own eyes that it can have a drag-and-drop CMS experience? Click around this theme in Stackbit and see.

Create with Stackbit


Why Jekyll isn’t perfect

Okay, actually, no one’s wrong, per se, and certainly not lying, about newer SSGs (and their templating languages) helping you develop components easily.

I just wanted to point out that componentizing a site so that you can give content authors a Wix-like drag-and-drop experience comes from:

  1. architecting a data model for that purpose
  2. architecting your static site generator templating for that purpose

You don’t need a JavaScript-based SSG or a “hydrating” SSG or a “modern” SSG or anything of the sort to do really fancy things with “components.”

“Components” are a way of thinking , not a property of a specific SSG templating language.

However, there are some related problems you might run into like:

The syntax can be heavy

Liquid doesn’t really love objects & arrays – particularly not making it easy to instantiate them as literals.

As soon as you want to pass around particularly complicated structured data, or do any fancy preprocessing of it, the amount of Liquid that you have to write really starts to explode, compared to the amount of JSX or Vue.js templating code (which JavaScript – including NPM package imports – slips right into natively) that you have to write.

But also, the syntax can be light

That said, when you don’t have heavy computation to do, I find Liquid’s plain-HTML-like syntax much cleaner and more concise than React’s or Vue’s templating syntaxes, which is why I’m defending Jekyll in the first place.

Here’s what a basic component looks like in React:

import React from "react"

export default function Home() {
  return <div>Hello world!</div>
}
Enter fullscreen mode Exit fullscreen mode

Here’s what that same component looks like in Liquid:

<div>Hello world!</div>
Enter fullscreen mode Exit fullscreen mode

The Jekyll ecosystem is small

It’s not JavaScript all the way down

When you’re using Jekyll, any custom computation you need that exceeds the power of Shopify’s Liquid templating language has to be defined in the Ruby programming language.

I’ll admit, it’s really nice to use one programming language – JavaScript – in:

  1. The front-end code you deliver to site visitors’ browsers alongside your HTML and CSS (in Jekyll, that’s JavaScript).
  2. The HTML templating code (in Jekyll, that’s Liquid).
    • Jekyll won’t let you randomly call Ruby’s .map{} within Liquid template code. You have hand-add Ruby code to the Liquid specification as a “Liquid filter” using Jekyll’s “plugins” functionality.
    • React/Vue-based SSGs, however, will let you randomly call JavaScript’s .map() within their templating languages, because it’s built into the syntax of the templating languages themselves that you’re allowed to do that.
  3. Deep-back-end functionality (in Jekyll, that’s Ruby).

NPM > Gems

Let’s be honest, these days all the cool stuff – particularly for supporting web site generation – is an NPM package, not a Ruby Gem. Like libraries that:

Content editing tools are scarce

Headless CMS is tough

Jekyll is old, and it doesn’t bake in a presumption that you’ll be fetching external API-based headless CMS data into your build the way Eleventy does.

To use data from Sanity, Contentful, the Notion API, the Wordpress API, etc. you literally have to run (and possibly hand-write) code that dumps API-sourced data into files on your filesystem that Jekyll can understand, before running jekyll build. (A couple of pre-written libraries: jekyll-contentful-data-import, Sourcebit.)

You can 100% build a really well-componentized theme in Liquid, as I’ve shown above. But the whole point of building a componentized theme is to give people a Wix-like experience through a drag-and-drop GUI editor, and most of the good content management user interfaces are built into API-based headless CMS websites.

Few Git-based CMS options

There are drag-and-drop content editors that play nicely with storing your content in the same Git repository as the site’s template codebase, like Netlify CMS and Forestry.io, but they’re not truly WYSIWYG experiences.

  • TinaCMS is a Wix-like experience, but it doesn’t support Jekyll. From what I can tell, it leverages the front-end code that newer site generators like Gatsby and Next “hydrate” into the “DOM” to support its drag-and-drop functionality.
  • The only Wix-like experience I’ve found so far that supports Jekyll is Stackbit … but who knows if they will forever? I can’t imagine that adding a live-edit drag-and-drop skin to Jekyll’s localhost engine has been easy for them to code, as amazing of a gift to the world it’s been that they figured it out.
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .