Understanding Bridgetown Part 2
Last Updated On: 2025-09-01 04:31:51 -0400
This blog post talks about how Bridgetown functions under the hood. I wrote this as an exercise to teach me enough about Bridgetown to port the Jekyll Minima theme to Bridgetown.
Just to be clear about my approach, I started with an out of the box Bridgetown site and then I didn’t have good luck with existing themes or the documentation. So everything I’ve written here has pretty much been teased out of an initial Bridgetown site and done in a very trial and error basis. I very much took the Julia Evans approach of learn by experimentation. Having recently read her debugging manifesto helped a lot.
I should note that I’m not going to create a theme in this blog post. What I do here is decompose Bridgetown’s file structure and concepts to get you ready to create a Bridgetown theme. And in a third or fourth blog post, I port the Jekyll Minima theme to Bridgetown.
Note: I also wrote about Bridgetown here.
How I Use Bridgetown
You should know that I’m a blogger and Jekyll refugee and I use Bridgetown solely as a blogging tool. I don’t care about any other application of Bridgetown so that’s how these theme overview is going to be slanted. What I care about is:
- Post Creation
- Table of Contents Generation
- Post Presentation
Sidebar: Pages and Posts
Bridgetown’s default theming includes two classes of content:
- Pages
- Posts
A page is something like an about page i.e. just a static web page where you can have some information.
A post is a permalink based web page, generally with a date based permalink like /2022-12-03-some-title.
Generally your site will have more posts than pages at least if you are a blogger like myself.
A key difference between pages and posts is the template that renders them. Pages are rendered using the page.liquid template and posts are rendered using post.liquid. And this rendering distinction is controlled using the YAML front matter what appears at the start of a page or post file with the
layout: post
or
layout: page directive
Bridgetown Theme Basics
To understand Bridgetown theming, you have to start with the directory structure:
. (the root directory)
bridgetown.config.yml -- this is the config file for the whole site; you likely need to edit this only once
bin/ -- where the executables live; you'll use bin/bridgetown constantly
config/ -- nothing to worry about; system level
frontend/ -- javascript and stylesheets; you likely need to know about this
node_modules -- ignore; it is node stuff
output/ -- this is where bridgetown generates the output it creates; your site or blog
plugins/ -- this is where any plugins you create go; technically a theme is a plugin but I don't actually believe that
server/ -- ignore; system level
src/ -- this is where the magic really happens!
The most important directory, by far, is src so we’re going to dive deep here. And I’m going to list the files that matter for template creation.
.
src/
_components
footer.liquid -- this is the persistent footer on every page in the site
head.liquid -- this is the html fragment that lives within the head tags on your site
navbar.liquid -- this is the navbar that appears at the top of every page
_data
site_metadata.yml -- this is site specific metadata like your email, twitter, etc
_layouts
default.liquid -- this is the overall or default layout for everything in your site
and this starts with an HTML tag, inserts HEAD tags, a BODY tag
and then your content whether page or post
page.liquid -- this is the template where your page content will appear
post.liquid -- this is the template where your content for a post will be inserted
_posts
2022-12-10-welcome-to-bridgetown.md -- The date of this file will vary but this is
the "hello world" post that Bridgetown generates for every site it creates; yes you
can delete it but keep it initially to give you a handle on what a post looks like.
404.html
This is the page served up when a 404 error occurs (404 means that the requested
page or post couldn't be found).
500.html
This is the page served up when there is a general error.
about.md
This is an about page for your site or blog; what the site is, your contact info,
etc goes here.
favicon.ico
This is an ICO file for your site or blog. This is the icon that appears in a
browser tab to the left of the page title.
images
This is where any images appear including your logo. The default logo is that
of Bridgetown itself.
index.md
This is the default home page for your created site or blog.
posts.md
This is the index to your posts
Sidebar: Understanding Liquid Templates
I’ve been in Ruby and Rails now since 2006 and this is my first time really encountering liquid in depth so if I sound a bit like a noob here, I am. Liquid templates are a templating language invented by Shopify that use curly braces like this:
NOTE: The curly brace characters below in my source code example BLOW up bridgetown’s build process so they are represented by (( )) characters. Use the actual curly brace character that normally appears on the keyboard above the [ ] characters.
(( page.title ))
Note: The above curly brace example would output the title of the page object. So a double curly brace is an outputting syntax.
The double curly brace syntax is an outputting syntax. Logic happens using a % sign plus a brace like this:
NOTE: See note above about curly brace characters.
(% if user %)
There are three key concepts for liquid templates:
- Objects – The content that liquid displays on a page/.
- Tags – These use (% %) syntax and works for if statements, variable assignment and conditionals.
- Filters – These change the output of a liquid object or variable. They are used within double curly braces and use a pipe character
Tags are pretty simply to understand but filters need some specific examples:
(( "/my/fancy/url" | append: ".html" ))
(( "adam!" | capitalize | prepend: "Hello " ))
The main reference to Liquid Templates is here. The actual liquid documentation is quite good and you should dig into it above and beyond the tiny snippet here.
Customizing bridgetown.config.yml
You need to start your template journey by opening this file an editor and customizing the url option. This needs to be set to something like:
https://blog.cartazzi.com/
or whatever your base site or blog url is.
Post Creation
Bridgetown lacks tools for automatically generating the date stamped post files like:
2022-12-10-welcome-to-bridgetown.md
This is, to me, an utterly inexplicable design decision. I don’t agree with it, I don’t like it and I think the creator of Bridgetown is mindbogglingly wrong on this one. I solved this for myself using a small Rake task embedded in Bridgetown’s Rakefile.
My solution with source code is described here. That post is pretty long so you should search for “Post Creation”.
Table of Contents Generation
I’m an old school blogger and I fundamentally believe that the root of a blog should have one of two things:
- Your latest posts
- A table of contents to all your posts
Bridgetown views itself as a progressive site generator (which it actually is) as opposed to a blogging tool so its focus is on site creation and sites have tables of contents that aren’t just a list of posts.
If you are looking for a table of contents to your posts on the home page, the trick here is to simply eliminate index.md and then rename posts.md to index.md.
Although the fix is easy, looking at the source of posts.md will nicely illustrate how Bridgetown actually works with content:
---
layout: page
title: Posts
---
<ul>
(% for post in collections.posts.resources %)
<li>
<a href="(( post.relative_url ))">(( post.data.title ))</a>
</li>
(% endfor %)
</ul>
If you have a lot of posts, you may want to consider adding [pagination](https://www.bridgetownrb.com/docs/content/pagination)!
The key take aways here are:
- The collections object which exposes pretty much everything in your Bridgetown site or blog.
- The post object which exposes the content of a post within the collection; posts have both top level attributes like relative_url and then a data element which includes the specific content for the post
Post Presentation
Posts are presented to the user using the template found in:
src/_layouts/post.liquid:
Here’s what that template looks like:
---
layout: default
---
<h1>(( page.title ))</h1>
(( content ))
I was surprised to see the post template referencing the page variableand I think that isn’t significant – likely a typo in how the template is instantiated. The more important takeaway here is the content variable which is (I believe) the output from the overall rendering of the post.
Putting It All Together - Creating a Bridgetown Theme
Here’s how I would go about putting together a Bridgetown theme:
- I’d start in the frontend directory and define any CSS and JavaScript.
- In the src/_components directory, I’d define footer, head and navbar.
- In src/_data, I’d define my site url.
- In src/_layouts, I’d define my default, my page and my post layouts.
- I’d brand my 404 and 500 pages because errors do happen and any chance to build your brand is something you want to do.
- I’d delete the index.md file and rename posts.md to index.md.
- Any images I needed, I’d place in src/images.
- I’d replace the favicon.ico file with one of my own.