Why WYSIWYG static site CMS's love Gatsby
24 Jun 2020
Please correct me if I’m wrong.
This is my current understanding of why most Jamstack CMSes with drag-and-drop WYSIWYG previewing seem to heavily favor using Gatsby as a static site generator.
React
It’s all about Gatsby’s choice to use React, a JavaScript framework originally meant for easily changing the appearance of a web page by manipulating its DOM, as its “template language” for rendering HTML into your static site at build time.
(Learning enough React to make “version 2” of my Gatsby experiments was quite an endeavor!)
Other static site generators, like Jekyll, ask you to code your logic in templating languages like Liquid (ahem – much lower learning curve).
For a CMS to create a simulation of your web site, it’d have to write an interpreter for converting code written in the templating language to HTML/JavaScript (which web browsers can actually understand).
Unless the template code is just JavaScript. Then the CMS can simulate your web site with very little effort.
Ultimately, it’s probably not so much that WYSIWYG drag-and-drop content management systems love Gatsby as it is that they love React.
Gatsby renders 2 copies of your site
Gatsby does a little “bonus” when it comes to React: it uses it to render two copies of your web site at build time.
As HTML
Like all static site generators, at “build” time, Gatsby produces a bunch of HTML (and CSS and JavaScript) for each “page” of your web site that gives visitors a full-featured copy of the page’s “elements” when they inspect the HTML behind “page source” in their browser.
If your homepage is supposed to have <div>Hello world</div>
in it, that HTML will actually show up in “View Page Source” from a browser.
As JavaScript
When viewing the “page source” of a Gatsby-rendered web page, you might notice references to JavaScript files with funny names.
These are spare copies of the React components you wrote for the “build server.” Gatsby put copies of them into the browser-available JavaScript within your page.
These “spare copies” of your React components can be be used to control the DOM that, more than the “page source” behind your web page, actually represents what a visitor sees when they visit your web page.
Why?
Including some JavaScript in the “page source” of a web page for “later use” isn’t terribly unusual.
My blog’s HTML includes a small <script/>
definition of a JavaScript function called toggleExpanded()
in my “page source.”
When a visitor clicks on the toggle-arrows for my sidebar, toggleExpanded()
alters the DOM responsible for rendering my sidebar.
This shows or hides months and posts.
What’s a bit particular to Gatsby is that it puts (“hydrates”) all of the JavaScript responsible for defining your whole web page into browser-available JavaScript just in case the page needs further manipulation browser-side.
That might seem like overkill, but according to episode 71 of JS Party and the Gatsby Docs, modern web developers are already quite comfortable working with a full-fledged copy of a page’s DOM in JavaScript.
They likely have plenty of ideas about functionality dependent upon browser-side JavaScript – things far more glorious than my little “sidebar toggle.”
However, apparently even modern web developers like the comfort of knowing an approximation of the web page as visitors will see it exists directly in the page’s “source” because search engines favor such web pages.
What does this have to do with CMS?
When the “browser-ready” JavaScript includes full-fledged React components representing portions of your site, not just little functions like toggleExpanded()
, other people’s JavaScript code running in a visitor’s web browser can easily manipulate their way your site looks to them.
For example, code from a CMS.
The DOM for your page, as seen at https://preview.yoursite.com
by a legitmate content author, might change with each keystroke the author types into your site’s CMS.
In practice, I don’t think a lot of CMSes leverage Gatsby’s “bonus copy” of React components.
However, I suspect that CMSes that work as plugins / settings within your Gatsby project itself might become part of this “exported-to-the-browser-by-Gatsby” JavaScript and interact with the rest of the React components as a way of altering the DOM for a given visitor’s experience.
How does it work?
Take a look at my second Gatsby experiment.
The React component I wrote for Gatsby was called Xyzzy
and rendered a message
between two DIV
tags. I stored this code in a file in the Git repository that Gatsby Cloud / Netlify looks at (at build time) called /src/templates/xyzzy.js
.
Gatsby, at build time, replaces message
in my Xyzzy
component with Hello World
, ensuring that my “page source” contains <div>Hello World</div>
from the get-go. When I look at the “page source” of my home page, I also find the following HTML:
<link
as="script"
rel="preload"
href="/component---src-templates-xyzzy-js-d35216e.js"
/>
<link
as="fetch"
rel="preload"
href="/page-data/index/page-data.json"
crossorigin="anonymous"
/>
Reading /component---src-templates-xyzzy-js-d35216e.js
, I find that the JavaScript within includes a snippet that seems to give the visitor’s browser a way to alter Hello World
by executing JavaScript:
var t=n.pageContext;
return a.a.createElement("div",null,t.frontmatter.message)
Reading /page-data/index/page-data.json
, I see:
{
"componentChunkName":"component---src-templates-xyzzy-js",
"path":"/",
"result":{
"pageContext":{
"frontmatter":{
"template":"xyzzy",
"message":"Hello World"
}
}
}
}
Personally, I don’t know enough JavaScript to figure out how to pass a new value to t.frontmatter.message
in /component---src-templates-xyzzy-js-d35216e.js
, but seeing that it exists as part of my web page’s browser-side JavaScript assures me that a good JavaScript programmer could figure it out.
Particularly if such code were also included by Gatsby as part of the page’s browser-ready JavaScript (which I think is how TinaCMS works).
What I think each CMS actually does
TinaCMS
TinaCMS, I believe, actually interacts with code like /component---src-templates-xyzzy-js-d35216e.js
.
(More specifically, I think it adds extra code to such files.)
TinaCMS consists of even more browser-side JavaScript that, when writing your source code for Gatsby, you ask Gatsby to include in every page’s browser-available codebase.
Therefore, I’d guess that TinaCMS’s browser-side codebase is interacting with the standard browser-side React components injected into each page of your site by Gatsby.
- (Note: Typically, you’d only inject TinaCMS code into, say,
https://preview.yoursite.com
, not into the realhttps://yoursite.com
.)
Any highly active CMS + Gatsby Cloud previews
When you set up a “development” / “preview” Gatsby site like https://preview.yoursite.com
to “listen” to data changes emanating from a CMS that issues data over its API with every keystroke such as Sanity…
…I would guess that the “listener” code within https://preview.yoursite.com
might run in your web browser and interact with the browser-side React components copies Gatsby injected into each page of your web site.
I’m not sure, but it seems like a reasonable guess?
Looking at the HTML of such a “preview” site, it has completely different JavaScript files and doesn’t have a hard-coded <div>Hello World</div>
in its “source” at all, so it’s possible that Gatsby Cloud previews are, structurally, a little more like Stackbit than like TinaCMS.
Sanity Studio
Approach 1
I don’t think Sanity Studio pays any attention to the /component---src-templates-xyzzy-js-d35216e.js
embedded within https://yoursite.com
.
Instead, I think Sanity Studio “cheats” by having you embed pages, hosted in something like Gatsby Cloud as described above (such as https://preview.yoursite.com/page_corresponding_to_the_content_you_are_editing
), into an <iframe/>
within its user interface.
Approach 2
Alternatively, if I’m reading the docs correctly, there’s also an option to copy/paste the code for actual React components you wrote, like Xyzzy
or BasicDiv
, into the configuration of Sanity Studio.
From those, the studio can render visual simulations of your content as appropriate.
Data entry into Sanity would result in edits to the DOM of the simulations.
Stackbit
I suspect Stackbit might be taking advantage of the fact that it asks you to let it see the Git repository where you’ve stored the actual React components you personally wrote.
I don’t think it’s paying any attention to the /component---src-templates-xyzzy-js-d35216e.js
embedded within https://yoursite.com
.
Instead, rather like Sanity Studio’s second approach, I think Stackbit builds its own simulation of your page out of the “raw” React components in your codebase.
Upon doing data entry into Stackbit, it would edit the DOM of its own simulation.
Magnolia CMS
Magnolia CMS is a little much for me to follow, but I think it, like Stackbit, is already privy to the filesystem in which you’ve stored your raw React components like Xyzzy
and BasicDiv
.
Therefore, it builds its own simulation of your pages and edits the simulation when you do data entry.
I don’t think Magnolia CMS pays any attention to the React components embedded within https://yoursite.com
within files like /component---src-templates-xyzzy-js-d35216e.js
.
Conclusion
In the end, I’d say that most CMSes are more interested in the fact that you use React as a templating language, which makes it easy for them to build simulations of your site, than in anything Gatsby itself does (like providing copies of the React components in the browser-side source of your site).
That said, like React, Vue is a JavaScript framework developed around browser-side JavaScript execution, and it seems the Nuxt static site generator uses Vue as a templating language the way Gatsby uses React, but I don’t see nearly as much love for it among WYSIWYG CMSes as I do Gatsby.
Maybe that’s just a market share choice, or maybe I’m missing something else technical that makes so many CMSes play nice with Gatsby.
I suspect things will become clearer as I work my way through the Jamstack CMS and SSG ecosystem, but it’s nice to write out a checkpoint of my understanding today.
Posts in this series
- Part 1 - Gatsby for novices and dabblers
- Part 2 - Gatsby Minimum Viable Build
- Part 3 - Gatsby React Minimum Viable Markdown Template / Component
- Part 4 - Gatsby React WYSIWYG CMS-Friendly Markdown
- Part 5 - This Article
- Part 6 - Sanity CMS Minimum Viable Build
- Part 7 - Gatsby Minimum Viable Sanity Template
- Part 8 - Gatsby Cloud live previews for Sanity-based sites
- Part 9 - Heroku live previews for Gatsby + Sanity sites
- Part 10 - Movable page builder components in Sanity CMS