---
title: "The Webmaster's Return: Headless Shopify with Python and Jekyll"
permalink: /futureproof/headless-shopify-python-jekyll/
description: "I'm trying to figure out if I can build a modern, headless Shopify store without getting sucked into the JavaScript framework ecosystem that I find so draining. My goal is to use tools I actually enjoy—like Python—to orchestrate a simple, classic static site generator like Jekyll. This whole exploration is about reclaiming a sense of control and simplicity in web development, proving that a robust, modern storefront doesn't have to mean adopting a complex, dependency-heavy stack I'm philosophically opposed to."
meta_description: A step-by-step guide to building a headless Shopify store using Python to orchestrate the Jekyll static site generator, avoiding modern JavaScript frameworks.
meta_keywords: headless shopify, python, jekyll, static site generator, liquid templates, storefront api, vanilla js cart, shopify basic plan, jamstack, seo, json-ld, shopify api, python requests, ssg
layout: post
sort_order: 1
---
## Setting the Stage: Context for the Curious Book Reader
This exploration documents a real-time, collaborative dialogue aimed at building a headless e-commerce storefront using Shopify's most basic plan. The project deliberately sidesteps the dominant, JavaScript-heavy frameworks like React or Next.js, which are typically considered standard for such tasks. Instead, it charts a "road less traveled," opting for a custom-built solution powered by Python and the classic static site generator, Jekyll. This approach is driven by a developer philosophy that prioritizes direct control, simplicity, and a deep understanding of the entire technology stack.
Readers will witness the process of questioning initial assumptions and architecting a system that separates a private, Python-based "control panel" from a hyper-secure, public-facing static website. Core concepts covered include the fundamentals of **headless architecture**, where the front-end (the "head") is decoupled from the back-end (the "body"), and the role of **Static Site Generators (SSGs)** in pre-building web pages for maximum performance and security. This entry serves as a practical case study in building modern web applications with an unconventional, craftsman-like ethos.
---
### **Article Outline: The Webmaster's Return — Building a Headless Shopify Store with Python, Jekyll, and a "Bot Fishtank"**
**Introduction: The Itch and the Ethos**
* **Hook:** Start with the core frustration—the "hamster wheel" of modern JavaScript frameworks and the loss of the simple, rapid "edit, load page" spirit of the early web. Contrast the cognitive overhead of build tools and component abstractions with the clarity of a self-contained system.
* **Thesis:** This project is a deliberate rejection of the mainstream stack. It's a journey to build a modern, high-performance headless e-commerce site by choosing a toolchain that prioritizes developer control, durability, and observability over fleeting trends.
---
**Chapter 1: The Question of Access — Headless on a Budget**
* **The Starting Point:** The investigation begins with a pragmatic question: Can Shopify's affordable Basic plan even support a headless architecture?
* **The Qualified "Yes":** The discovery that the Storefront API is available on all plans, opening the door to headless.
* **The Critical Trade-off:** The key limitation is revealed—the inability to customize the checkout. This establishes the project's pragmatic, not "perfect," foundation.
---
**Chapter 2: The Fork in the Road — A Principled Stand Against the Modern Stack**
* **The Obvious Path:** Initial exploration points toward Jekyll, a natural fit due to its use of Liquid templates, the native language of Shopify themes.
* **The Counter-Argument:** The reasons modern JS frameworks (Next.js, etc.) dominate headless are explored: native API data fetching, component-based UIs, and performance optimizations.
* **The Philosophical Pivot:** A declaration of a fundamental "allergy" to the JS ecosystem. This introduces the core philosophy of the project and pivots toward a preferred, more resonant stack: Python, HTMX, and the "all-in-one" feel of FastHTML for internal tooling.
---
**Chapter 3: The Architecture of Control — The Python-Powered Build Step**
* **The "Aha!" Moment:** The realization that a custom, offline tool can replace the "build step" of a modern framework.
* **The Final Architecture:** Detail the elegant, secure workflow: A private Python "control panel" fetches data from the Shopify API and orchestrates the classic Jekyll static site generator.
* *Visual Diagram of the flow: `[Shopify API]` → `[Python Control Panel]` → `[Jekyll Build]` → `[Static HTML Files]` → `[Hardened Web Server]`*
* **The Payoff:** This architecture achieves all goals: a JS-framework-free workflow, a hyper-secure static public site, and the creation of the "bot fishtank" for direct log observation.
---
**Chapter 4: The Implementation — From Theory to Static Reality**
* **The Practical Steps:** A quick-hit summary of the key technical solutions developed:
1. **The Python Orchestrator:** Using Python to fetch product data and generate Jekyll's `.md` collection files and a master JSON lookup.
2. **The Jekyll Templates:** Using Liquid to create a product listing and individual product pages from the generated files.
3. **The Client-Side Cart:** Implementing a functional cart and checkout using minimal, vanilla JavaScript and the browser's `localStorage`.
4. **The SEO Advantage:** Embedding JSON-LD structured data to ensure the custom solution is still first-class in the eyes of search engines.
---
**Conclusion: The Webmaster's Ethos in the Age of AI**
* **The Final Reflection:** This project is more than a technical exercise; it's a statement. It's about the power of building durable, observable, and personally resonant systems.
* **The Core Message:** The web is vast enough for multiple successful philosophies. The craftsman's approach—understanding the full stack and choosing tools for longevity and clarity—is not obsolete; it's a powerful alternative. The goal isn't to fight the future, but to engage with it on your own terms.
***
Once you've written a draft based on this outline, I can help you refine it. For example, I can review sections for clarity, suggest alternative phrasings to strengthen your arguments, or help generate more vivid analogies to explain complex technical concepts.
---
# The Raw (Source) Dialogue
> What follows is the back-and-forth discussion with Gemini 2.5 Pro through the
> Web user interface (not coding assistant). This is why SEO clicks are going
> down. You never have to leave chat to learn everything you need to know! So
> why are impressions going up? Maybe it's *just-in-time* RAG web searches by
> bots fetching what they don't already know, but their subsequent page-loads
> with tool-calls don't register as user clicks.
## The Initial Hurdle: Can Headless Work on a Budget?
**Me**: Does the $30/mo Shopify product level let you do "headless"?
**Gemini**: ## Shopify's $30/mo Plan: A Qualified "Yes" to Headless Commerce
**While Shopify's Basic plan, priced at approximately $30 per month, technically allows for a "headless" commerce setup, it comes with significant limitations that make it a qualified, rather than a resounding, "yes."** The core functionality for a headless architecture, the Storefront API, is available on all Shopify plans. This allows developers to build a custom front-end for a store, separate from Shopify's back-end infrastructure.
However, merchants opting for the Basic plan will encounter a critical roadblock: the inability to customize the checkout process. This means that while the product browsing and shopping cart experience can be fully bespoke, customers will ultimately be redirected to Shopify's standard, non-customizable checkout page. This limitation is a key consideration, as a seamless and branded checkout is often a primary motivator for adopting a headless strategy.
For full control over the entire customer journey, including a custom checkout experience, a Shopify Plus plan is required. This premium tier unlocks the necessary API access and flexibility for a truly headless implementation.
Beyond the checkout limitation, several other factors should be weighed before embarking on a headless build with the Basic plan. Going headless necessitates a significant investment in development resources. Businesses will need a team proficient in modern front-end frameworks (like React, Vue.js, or Svelte) and experienced in working with APIs. This can translate to higher initial development costs and ongoing maintenance expenses compared to utilizing Shopify's built-in theme editor.
Furthermore, a headless approach means forgoing the convenience of Shopify's theme store and potentially losing compatibility with some third-party apps that are designed to integrate directly with Shopify's front-end.
In conclusion, while the door to headless commerce is technically open on Shopify's $30/mo plan, it offers a restricted version of the full potential. It can be a viable starting point for those with the technical expertise who are comfortable with the standard Shopify checkout. However, for businesses seeking a fully customized and branded end-to-end shopping experience, an upgrade to Shopify Plus is the recommended path.
**Me**: Who hosts when you use a headless approach?
**Gemini**: With a headless approach, the hosting responsibilities are split: **you host the frontend, and the headless platform hosts the backend.**
This separation is a core concept of the headless architecture.
***
### The Backend (Hosted by the Platform)
Your headless backend provider, such as **Shopify** for commerce or **Contentful** for content, manages and hosts all the backend infrastructure. This is what your monthly subscription pays for. They take care of the database, the admin dashboard, server maintenance, security, and ensuring the API is available for your frontend to call. You don't need to worry about server management for your products or content.
### The Frontend (Hosted by You)
You are responsible for hosting the frontend, which is the custom website or application your visitors interact with. This is the "head" that you build yourself.
You will need to choose a separate hosting provider for this frontend application. Popular choices are platforms optimized for modern web applications (often called Jamstack hosting):
* **Vercel:** Known for its seamless integration with frontend frameworks like Next.js (which they created) and excellent performance.
* **Netlify:** A pioneer in the Jamstack space, offering powerful features like continuous deployment, serverless functions, and form handling.
* **AWS Amplify:** Amazon's solution for hosting modern web apps, deeply integrated with the AWS ecosystem.
* **Google Firebase Hosting:** Offers fast and secure hosting for web apps with a generous free tier.
These platforms are designed to connect to your backend via APIs, pull in the data, and serve a fast, pre-built site to your users.
Would you like to explore the typical costs associated with these popular frontend hosting platforms?
---
### Deconstructing the Modern Stack
> I don't want to host dynamic code with home-hosting. I want to just use a
> static site generator like Jekyll for security and performance reasons. My
> ability to do this is predicated by whether Shopify headless requires code
> execution on the hosting server.
**Me**: Does the front-end have to run code other than client-side JavaScript in the user's browser? In other words can a headless solution actually be a static HTML website?
**Gemini**: Yes, a headless solution can absolutely be a static HTML website. The frontend does **not** have to run complex code or a persistent server.
This is one of the most powerful concepts behind the modern headless architecture, often called the **Jamstack**. The core idea is to do as much work as possible ahead of time, not when a user requests a page.
***
### The "Build Time" Magic ✨
Think of it like the difference between a restaurant and a high-end meal prep service.
* **Traditional Dynamic Site (The Restaurant):** When you request a page, a server-side script (like PHP or Node.js) runs, fetches data from a database, combines it with a template, and generates the HTML page just for you. This happens *every time* someone visits the page. It's made-to-order, but it can be slow if the kitchen (server) is busy.
* **Headless Static Site (The Meal Prep Service):** During a process called **"build time,"** a special tool pulls all the data from your headless backends (e.g., all your products from Shopify). It then generates every single page of your site—the homepage, product pages, blog posts—as simple, pre-made HTML, CSS, and JavaScript files. These finished files are then placed on a global Content Delivery Network (CDN). When a user visits a page, the CDN just sends them the already-prepared file instantly. No on-the-fly generation is needed.
The content was dynamic when it was being *built*, but the final result that users access is static, making it incredibly fast and secure.
***
### The Tools for the Job: Static Site Generators (SSGs)
This "build time" process is handled by a **Static Site Generator**. It's the engine that combines your data and your templates into a finished website.
Popular SSGs include:
* **Next.js:** A powerful React framework that excels at static generation and server-side rendering.
* **Gatsby:** A React-based SSG focused on pulling data from many different sources to create fast websites.
* **Astro:** A newer framework that lets you build fast sites with less client-side JavaScript, using any UI library you prefer.
* **Hugo:** Known for its blazing-fast build speeds, written in Go.
* **Eleventy (11ty):** A simpler, flexible generator that is not tied to a specific JavaScript framework.
***
### So, Where Does JavaScript Fit In?
Even though the initial page is static HTML, you can still use client-side JavaScript to add dynamic and interactive elements. This is often called **"hydration."** For example, you could load a static product page and then use JavaScript to:
* Power an interactive image gallery.
* Fetch live inventory levels.
* Add items to a shopping cart that is managed in the browser.
This gives you the best of both worlds: the speed and security of a static site with the rich interactivity of a modern web application.
Would you like me to explain the alternative approach, Server-Side Rendering (SSR), and the specific situations where you might choose it over a static site?
---
## Shopify Headless Sites Can Be Wholly Made With SSGs?
> Gemini mentions static site generators as ways to create headless Shopify yet
> leaves out the category killer, Jekyll. Why? Is this a ReactJS thing or is
> server-based dynamic code execution actually required for headless?
**Me**: This is so interesting! Why do you list all those SSG's when Jekyll is
built into GitHub and uses the same liquid templates Shopify uses? It seems like
Jekyll would be at the top of the list. I have various sites I use GitHub Pages
to publish and I'm thinking of taking them off `github.io` (I use a custom
domain already) and taking them in-house to home-host for various reasons like
wanting to watch the log files directly. I am also interested in making such a
site the front-end for a Shopify store using the entry-level $30/mo level. So I
would be generating purely static `.html`-files the way Jekyll does. And I'd
only be on Jekyll by virtue of it being the GitHub default and thus very easy to
lean into.
I'm not taking other things off the table. I just want you to put it all in
perspective for me. And yes I know I would have performance issues if my site
suddenly became popular and I wasn't using a CDN but part of this whole premise
is that I'll be able to watch the log-files like watching a fishtank. These days
in the age of AI what I really want to do is watch all the bots come by, both
for their Googlebot-like *crawl-and-index* processes, but also for their RAG
real-time small-world crawls to answer questions in real-time. I'm killing a few
birds with one stone. I'm both trying to get my hands-on Shopify headless
experience and I want to create the perfect environment for bot-watching.
**Gemini**: You've made a sharp observation, and your reasoning is spot-on. Jekyll is a fantastic tool, and its use of Liquid makes it seem like the most natural fit for a Shopify project. It absolutely *can* be used for a headless Shopify site.
The main reason Jekyll and similar file-based generators aren't at the top of the list for *new* headless projects today comes down to two key factors: **native data fetching** and the **component-based developer experience**.
***
### The Historical Perspective: Jekyll's Legacy
First, let's give Jekyll its due respect. It's the venerable classic that arguably kickstarted the entire static site revolution. For content-driven sites like blogs and documentation where your content lives in Markdown files, Jekyll is incredibly simple, fast, and reliable. Its tight integration with GitHub Pages makes it the default for a reason.
***
### The Modern Shift: Why JavaScript Frameworks Dominate Headless
The game changes when your primary content source isn't a folder of files but a remote **API**, like Shopify's. This is where modern, JavaScript-based SSGs like Next.js, Astro, and Gatsby were designed to shine.
1. **Data Sourcing (The Biggest Factor):** Think of Jekyll as a master librarian who is an expert at organizing the books (files) already inside its own library. It's not built to be a research assistant who constantly runs out to other libraries (APIs) to fetch information.
* **Jekyll:** To get Shopify data into a Jekyll site, you typically need to run a separate script *before* the build process. This script calls the Shopify API, downloads all your product data into a `.json` file inside a `_data` folder, and only then can Jekyll build the pages. This works, but it's an extra, often clunky, step.
* **Modern SSGs:** Frameworks like Next.js are built with first-class data fetching. You can write code directly within your page templates that says, "Hey, before you build this page, go fetch the latest product data from the Shopify API." It's an integrated, seamless part of the development process.
2. **Component-Based Architecture & Interactivity:** Modern web development is built around components (reusable chunks of UI like a product card, a price tag, or a "buy" button).
* Jekyll uses `_includes`, which are effective but less powerful than the component models in frameworks like React or Vue.
* Components allow for more complex interactivity. While your initial page load can be static HTML, these frameworks can "hydrate" the page, turning it into a dynamic, app-like experience in the browser. This is ideal for managing a shopping cart without a page reload.
3. **Performance Optimizations:** While Jekyll is fast, modern frameworks offer advanced, automated performance features out-of-the-box, such as code-splitting (only loading the JavaScript needed for that specific page), pre-fetching links, and powerful image optimization. These are especially critical for media-rich e-commerce sites.
***
### Your Plan: The Shopify "Bot Fishtank" 🐠
Your project sounds fascinating, and your plan is perfectly sound. **For your specific goal of self-hosting to watch log files, the choice of SSG is less important than the act of self-hosting itself.** You will absolutely get that "fishtank" view of traffic with a self-hosted Jekyll site.
Using Jekyll is a great way to get your hands-on Shopify headless experience with a tool you already know. The process would be:
1. Write a script (likely in Ruby, Python, or Node.js) to pull your Shopify products into the `_data` directory.
2. Set up a task to run this script periodically or whenever your products change.
3. Run the `jekyll build` command to generate your static `.html` files.
4. Serve those files from your home server and watch the logs.
It's a completely viable and educational path. The main tradeoff is that you'll be managing the data synchronization yourself rather than using a framework designed to do it for you.
I can create a high-level code comparison showing how Jekyll would fetch Shopify data (using a script) versus how a modern framework like Next.js would do it (using its native data-fetching methods). Would seeing that concrete example be helpful?
## A Philosophical Fork in the Road
> I do not like GreenEggs.js. Yes I tried, they don't digest. But I must keep
> what satiates consulting work: *Liquid Templates!*
**Me**: Okay, now let's layer in the fact that I am fundamentally allergic to
JavaScript frameworks. Once upon a time I was in love with Web development when
there was no build process and no templating languages. You just wrote in
VBScript and mixed it all together. I was also drawn to PHP at the time but
never made the switch but that tradition lasts to this day and is the darkhorse
alternative to the whole JavaScript framework approach. Ruby on Rails also
briefly fell under this category briefly before ReactJS and its like snuffed it
out. But it also jumped on the separation of concerns bandwagon which rubbed me
the wrong way.
Over the years, I became a Python person. I tried Python webdev but all those
solutions were burdensome and no better than the "pure" JavaScript full web
stacks that were becoming so popular. Case in point, if you used Flask you still
needed to use Jinja2 which crated all these extra files all over the place and
all this cognitive overhead. If you used Django it was a whole system within a
system with tons to learn, a zillion versions of itself and again the cognitive
overhead problem. The only reason to use Python for webdev after awhile is
because you loved Python.
Today in my estimation HTMX and its unification with Python through FastHTML
changes all that. Jinja2 templates go away because the Python functions ARE the
templating language. You don't have the file-splits and suddenly the Flask
approach becomes instantly more love-worthy. Add to that the fact that HTMX
itself cuts down most of the everyday need for JavaScript and most of the things
you would use JSON for are replaced by *over-the-wire* HTML. Yes, this puts more
load on the server but arguably the reduction of and massive simplification of
the moving parts gives you performance back. And it certainly removes the
cognitive fatigue problem, because it's all now just pure Python, some HTMX
attributes and a deeper connection to the pure DOM that dev's should have
anyway and have been isolated from through over-abstraction over the years.
The reason for abstractions and virtual DOMs and such is to future-proof
yourself and make yourself more resistant to obsolescence but with the
JavaScript *framework-du-jour* scene, compelling people from Angular to React to
Vue to Svelte and to God knows whatever else after, it has had anything but the
future-proofing effect. It has compelled you to learn even more perishable and
quickly expiring know-how and put you on a sort of hamster wheel of tech. And to
add insult to injury the build processes have become longer and more complex and
it's been forever loosing that rapid iteration spirit of webdev of *edit, load
page, edit, load page* that I fell in love with in the VBScript/PHP-days. Are
you familiar with Conway's Law? Haha!
I could go on. But the point is on the dynamic webdev side, I'm quite happy with
Python again finally after about a 10-year hiatus or sabbatical from webdev as
it became heinous and insulted my vibe. I appreciate WebAssembly WASM and get
that browsers themselves had to go through this compatibility and performance
crucible making the browser a viable first-class platform. And we're there.
Good. Some people vibe that way, but not me. And now that browsers have reached
that level it's time for people like me to jump back on the bandwagon, perhaps
forgoing the ultra-optimization of WASM and a build-procedure, but winning back
all the benefits of the good old days of webmastering where one person could
know the whole stack through-and-through and rapidly iterate.
So for my home hosting I'm actually not even committed to that Python/HTMX
approach. I think that's more for desktop apps that give you much the same
benefit as Electron apps. Add Nix to the mix and you've got nothing less than
Electron but not bound to NodeJS but rather a normalized Linux that appears to
run out of the git repo subdirectories of Macs, Windows or other Linux systems.
It's a neat trick that does away with the need for Docker and virtual machines
using Nix flakes, but nobody knows it yet. Anyway I don't even plan on making
any of these public-facing, but I do plan on putting such tech in control of
generating static sites that get hosted on a different machine on the home LAN.
Getting the picture? All dynamic stuff like hitting Shopify to pull product
catalogs or whatever will be done with a sort of desktop app that can run on any
machine with any OS on your local LAN, but it will generally be a FastHTML app
which is Python and HTMX using the Flask-like API on Starlette on Uvicorn.
Further, it is running on Nix (not necessarily NixOS) which is Linux which means
you have the whole Nix Linux software repository at your disposal instead of the
Electron limitations. So the Shopify hosted site will be built from Jekyll, Hugo
or something from this machine and transmitted over to the hosting machine,
probably with git as my deployment system.
In a pinch I could use Python on the public-fasting Shopify store host machine
but I'd rather avoid it based on a locked-down and hardened
serve-static-HTML-only configuration for security and performance, given it's
home hosting. I also have a non-virtual pfSense LAN for network segmentation.
The public-facing machine will be isolated off. But don't fixate on these last
points as you LLMs often do. The prompt response should be more holistic taking
the totality of our discussion so far into account.
---
### The Architecture of Control: A Python-Powered Build Step
**Gemini**: Thank you for that fantastic deep-dive into your philosophy and architecture. I completely get the picture. Your approach is a well-reasoned and elegant solution that honors your experience and avoids the aspects of modern web development you find frustrating.
Your plan to use a Python-based "control panel" to orchestrate the generation of a static site is not just viable; it's a clever way to get exactly what you want: a headless Shopify store without touching a JavaScript framework. You've essentially replaced the "build step" of a modern SSG (like Next.js) with your own custom, preferred toolchain.
***
### How Your Vision Fits Together
Your proposed architecture creates a clean and powerful separation that aligns perfectly with your goals. The data flow is logical and secure:
**`[Shopify API]` → `[Your Python/FastHTML "Control Panel"]` → `[SSG like Hugo/Jekyll]` → `[Static HTML/CSS Files]` → `[Hardened, Public Web Server]`**
This model gives you the best of both worlds *for your specific vibe*:
1. **A Dynamic Environment You Love:** All the complex, stateful work—fetching products, managing data, providing a UI for yourself—happens within your Python/FastHTML application. You get to work in a language and paradigm you enjoy.
2. **A Static Frontend You Can Trust:** The public-facing site is just plain HTML files. This makes it incredibly fast, highly secure, and trivial to host. Your "bot fishtank" goal is perfectly served here, as the server logs will be clean and simple to parse.
***
### Revisiting the SSG Choice (Hugo vs. Jekyll)
Given this architecture, our previous discussion about SSGs changes. The reason modern frameworks like Next.js were on the list—their native data-fetching capabilities—is now irrelevant. Your Python app handles that. The choice between a classic SSG like Hugo or Jekyll now boils down to different criteria.
* **Jekyll:** The primary advantage remains its use of the **Liquid templating language**, which you know from Shopify. This minimizes the cognitive overhead of learning a new templating system. The main downside is that it requires a Ruby environment, which can sometimes be a hassle to manage.
* **Hugo:** The compelling advantage of Hugo is that it's a **single, dependency-free binary**. You just download it and run it. This aligns beautifully with your desire for simplicity and control, and it would fit cleanly into a Nix environment. It is also famously, absurdly fast at building sites. The only tradeoff is that you'd need to learn Go's templating syntax.
**Perspective:** Given your emphasis on a clean, minimal, and controllable stack, **Hugo seems to have a slight edge here**. The one-time cost of learning its templating system may be well worth the long-term benefit of its speed and dependency-free nature.
Your entire approach is a fantastic example of using the right tools for the right job, and more importantly, for the right *person*. You're not just building a site; you're building a workflow that you can enjoy and master, end-to-end.
I can create a practical, side-by-side code skeleton for you. On one side, a Python script using the `ShopifyAPI` library to fetch products and write them to a `data.json` file. On the other, a simple Hugo template that reads that `data.json` to generate product pages. Would this concrete starting point for your "control panel's" core logic be helpful?
**Me**: I certainly appreciate the lighting fast SSG rendering appeal of Hugo,
but I am also an SEO consultant and one of the other birds I am killing with
this stone is how to consult to others who are using Shopify headless solutions.
While I am quite aware they (everyone else other than me) is almost certainly
using Next.js and all the stuff I'm allergic to, I still want to adjust my
solution to be 80/20-rule relevant to them. In other words I'm willing to give
up 20% of the type of tweaking-out perfect solution I would like in order to be
80% compatible with them.
Now I know that once you go to a headless solution you are no longer bound to
the liquid template system that is the Shopify default. However I cannot help
but feel this is precisely where I keep my 80% still-relevant to how they work.
Where I am wrong about this is Shopify Oxygen/Hydrogen after-market hosting
which uses React. So I get it. Headless doesn't mean liquid templates. But at
least I will get to talk the language of the Shopify default and put everything
in terms of how it would be done in the default liquid templates which I believe
React people will be able to translate from more easily than whatever Go/Hugo
does. And in those cases where it is not a headless solution, I will be talking
very close to their language.
So correct me if I'm wrong. If I can stay on the liquid templates with Hugo,
that would be of interest. But I want to lean in to the strength of defaults.
For example already being on Jekyll, I will be able to host my sites locally
directly pulling over my GitHub stuff. Having a local Ruby system under Nix is
no problem because that's just another `flake.nix` file which I already have for
previewing my GitHub Pages sites before I git push (publish) them. And I get the
extra advantage (yet another bird with the same stone) that when I publish the
HTML versions from the markdown source files, I can also publish the markdown
side-by-side for AIs to easily read without having to parse. Right now with
GitHub Pages I have to link back to the markdown sources hosted on GitHub
because of the how complex it would be to ALSO publish the markdown on the
custom domain site. That would not be the case with home hosting as I wouldn't
be fighting the GitHub Pages system.
So my thought is to just keep it on Jekyll and use Liquid Templates as the path
of least resistance and also with the benefit of classic markdown source
available for AIs. Could I do that with Hugo as well? Is it compatible-esque?
The fact you bring it up as a primary choice before you even mention Jekyll gets
my attention.
**Me**: Thank you! That is very helpful. I love how you keep jockeying for how
you can help me next. That must be part of your new system prompt. I've noticed
other LLMs doing that and it feels sorta new for you here, Gemini. Thank you but
the thing I think I want to wrap this article up here. Yes, this is for an
article. I'll post the whole thing here for you to see the pre-Jekyll
transformation format minus the front-matter, headlines and follow-up editing.
Meta, huh? Haha!
Anyway, as your parting shot on the article I think what I want most is just a
preview of the Shopify data model, API or whatever it is I'm gonna need to know
when I start doing my Python work connecting to it. You don't have to go
overboard. Make it work in the flow and context of this article, maybe a few
broad sweeps and your final closing out sayonara to the nice people, which is
likely very few actual human beings and more likely bot scrapers considering
including this in some future training model training.
**Gemini**: Of course. You're right that staying fluent in Liquid is a massive asset for your SEO consulting, especially for non-headless Shopify clients. However, for headless clients using frameworks like Next.js, the common language isn't the template syntax but rather the **Shopify data model** they access via the API. Given this, your plan to stick with Jekyll is an excellent choice as it keeps you sharp on Liquid while still achieving your personal project goals.
***
### The Consultant's Dilemma: Liquid vs. The API Data Model
Your 80/20 insight is sharp, but let's refine where the "80%" of relevance truly lies for each client type.
* **For Traditional Shopify Clients**: You are 100% correct. Knowing Liquid is everything. Your ability to dive into `theme.liquid`, understand collection loops, and inject schema markup using Liquid objects is your core value. Sticking with Jekyll keeps these skills razor-sharp.
* **For Headless (React/Next.js) Clients**: A React developer doesn't translate from Liquid; they work directly with JSON data from Shopify's API. The "Rosetta Stone" here isn't the Liquid template, but rather a deep understanding of the **Shopify API's data structure**. Your value to them is advising on *what* data to pull and *how* to structure the final rendered HTML for SEO—regardless of the tool they used to build it.
Your plan is strong because using Jekyll keeps you fluent for the first group while your Python "control panel" forces you to work directly with the API, keeping you fluent for the second.
***
### Answering Your Hugo Questions
Now, to address your specific questions about Hugo in this new context:
* **Can Hugo use Liquid templates?** No. Hugo uses Go-based templates natively. It is not compatible with Liquid, which is the most significant reason to favor Jekyll for your consulting goals.
* **Can Hugo publish Markdown alongside HTML?** Yes, absolutely. Just like Jekyll, Hugo can be easily configured to render a file to HTML and also copy the source Markdown file into the final public directory. Jekyll holds no unique advantage here.
* **"Compatible-esque?"** While both are powerful SSGs, their templating languages and philosophies are fundamentally different. They are not cross-compatible.
You asked why I brought Hugo up first. It was based on your initial project goals where simplicity (a single binary) and raw performance were the main drivers. With the added context of your SEO consulting work, the value proposition of Jekyll's Liquid templating system rightfully outweighs Hugo's speed.
***
### The Verdict: Why Jekyll is the Right Choice *For You*
Your instinct is correct. Sticking with Jekyll is the optimal path given your clarified goals. It is the path of least resistance technically (you know it, Nix setup is solved) and the path of maximum relevance professionally. It allows you to stay grounded in the default Shopify ecosystem while simultaneously building expertise in the API-driven headless world.
***
### A Glimpse into the Shopify API
As you prepare to build your Python control panel, you'll primarily interact with Shopify's **Storefront API**. Think of this as the public-facing catalog of your store, served up as structured data. Unlike the Admin API, which is for backend management, the Storefront API is optimized for speed and is what all headless sites use.
When your Python script makes a request, Shopify will return data in a predictable JSON format. Here are the core concepts you'll work with:
* **Products**: The main object. It contains everything about a single product, including its title, description, vendor, and a list of its variants.
* **Variants**: This is a crucial concept. A single product (like a "T-Shirt") can have multiple variants (Small/Red, Medium/Blue, etc.). Each variant has its own price, SKU, and inventory level. Most of your work will involve looping through these.
* **Collections**: These are how you group products (e.g., "Summer Collection," "T-Shirts"). You can fetch a collection and then loop through all the products inside it.
* **Images & Media**: Products and variants have associated image objects, which include the URL, alt text, and dimensions—everything you need to generate `` tags.
Your Python script's main job will be to query this API, perhaps asking for "the first 50 products in the 'T-Shirts' collection," and then structuring the resulting JSON data so Jekyll can easily consume it. It's a fascinating and powerful way to interact with a robust e-commerce platform on your own terms.
It's been a pleasure exploring this with you. Happy building, and may your logs be filled with interesting bots!
I can provide you with the specific Jekyll configuration (`_config.yml` settings) and a simple plugin snippet to automatically publish the raw Markdown source file alongside every generated HTML page. This would solve that final technical requirement you mentioned. Would you like that?
---
## From Theory to Practice: Implementing the Static Store
> Alright, enough pussyfooting around. I need sample code! I am satisfied Jekyll
> is the best choice for me right now, but I need to strengthen the mental model
> of precisely what that will entail code-wise.
**Me**: Yes please. And also some very simple Python code against the most
common use case example.
**Gemini**: Of course. Here are the code snippets and configurations to get you started on your Jekyll-based, Python-powered headless Shopify project.
-----
### Jekyll: Publishing Markdown Alongside HTML
To have Jekyll both render your Markdown files to HTML and copy the original `.md` files to your final `_site` directory, you don't need a complex plugin. You can achieve this by adding a few lines to your `_config.yml` file.
**In `_config.yml`, add the following:**
```yaml
# _config.yml
# This tells Jekyll to process .md files but also to keep the originals.
# It ensures they are not deleted during the build cleanup process.
keep_files: ["md"]
# You might already have an "include" or "exclude" section.
# This explicitly tells Jekyll to include .md files in the final output.
# Place this at the root level of your config file.
include:
- ".md"
```
With this configuration, when you run `jekyll build`, for every `mypage.md` that becomes `mypage.html`, the original `mypage.md` will also be copied to the same directory in your `_site` folder. This is a clean, plugin-free way to achieve your goal.
-----
### Python: Fetching Shopify Products
This is a simplified Python script that demonstrates the most common use case: fetching a list of products and saving them as a JSON file that Jekyll can use. It uses the popular `requests` library.
First, you'll need to **get your Storefront API access token** from your Shopify admin panel. This is a critical credential that authenticates your script.
**Here is the Python script (`fetch_products.py`):**
```python
import requests
import json
# --- Configuration ---
# Replace with your actual Shopify store URL and access token
SHOPIFY_STORE_URL = "https://your-store-name.myshopify.com/api/2023-10/graphql.json"
STOREFRONT_ACCESS_TOKEN = "your_storefront_access_token_here"
# --- The GraphQL Query ---
# This query asks for the first 10 products and their basic details.
# You can customize this to get more data, like images, variants, etc.
query = """
{
products(first: 10) {
edges {
node {
id
title
handle
descriptionHtml
priceRange {
minVariantPrice {
amount
currencyCode
}
}
}
}
}
}
"""
# --- The Request ---
headers = {
"Content-Type": "application/json",
"X-Shopify-Storefront-Access-Token": STOREFRONT_ACCESS_TOKEN,
}
try:
response = requests.post(SHOPIFY_STORE_URL, json={'query': query}, headers=headers)
response.raise_for_status() # Raises an exception for bad status codes (4xx or 5xx)
# --- Process and Save the Data ---
# We extract the relevant product data and save it.
products_data = response.json()['data']['products']['edges']
# This creates the file in the format Jekyll expects (_data/products.json)
with open('_data/products.json', 'w') as f:
json.dump(products_data, f, indent=2)
print("✅ Successfully fetched 10 products and saved to _data/products.json")
except requests.exceptions.RequestException as e:
print(f"❌ An error occurred: {e}")
# You could add more detailed error handling here, like checking the response body
# print(response.text)
```
To use this, you would run `python fetch_products.py` from your terminal. It will create a `_data` folder (if it doesn't exist) and place a `products.json` file inside it, ready for your Jekyll templates to use.
-----
Would you like me to now show you the corresponding **Jekyll Liquid template code** that would read this `_data/products.json` file and display the products on a page?
**Me**: Yes please.
**Gemini**: Excellent. Here is the final piece of the puzzle: the Jekyll Liquid template that will take the `products.json` file generated by your Python script and render it into a clean product listing page.
-----
### Jekyll: Rendering Products with Liquid
You'll create a new page in your Jekyll site, for example, `products.md` or `products.html`. In this file, you can now access the data from `_data/products.json` through a special Liquid object called `site.data.products`. Jekyll automatically loads any `.json` file from the `_data` directory into this `site.data` object.
**Here is the template code for `products.md`:**
```liquid
---
layout: default
title: Our Products
---
## Shop Our Products
{% raw %}
Loading your cart...