Sign in

NON-TOXICNo ads · No shady algorithms

iiinova is part of the Atmosphere — an open, public network where you own your identity.

Bob Monsour

@bobmonsour.indieweb.social.ap.brid.gy
24 followers 2 following 463 posts

Web hobbyist and creator of the 11ty Bundle at 11tybundle.dev Brooklyn-born, New Jersey-raised, and educated in Florida and California, I’m now retired […] 🌉 bridged from ⁂ indieweb.social/@bobmonsour, follow @ap.brid.gy to interact

PostsRepliesMedia
Bob Monsour @bobmonsour.indieweb.social.ap.brid.gy · 58m
@riverpunk If you’re ever looking for ideas on how other people use various parts of #11ty, you might find this helpful: 11tybundle.dev
11tybundle.dev
The 11ty Bundle
Your curated source for discovering how the community is using 11ty, a simple, flexible, open-source static site generator. With loads of resources: 1780 blog posts from 513 authors across 54 categories, 39 starter projects, and much more.
000 0
Bob Monsour @bobmonsour.indieweb.social.ap.brid.gy · 16/10/2026
@semaj I worry about this a lot. I have an envelope labeled “If I’m dead” with some password info, but it’s not really enough. Thanks for yet another reminder.
010 1
Reposted by Bob Monsour
donthatedontkill @donthatedontkill.nantes.social.ap.brid.gy · 14/10/2026
Did some minor updated to my website. So it seemed like as good of a time as any to reshare it here. It's part of the indieweb so you can send me webmentions if that's what you get into. 😉 Fixed a few bugs, added a link to my pleroma account, moved a few things around. Nothing major but needed […]
nantes.social
Original post on nantes.social
002 2
Bob Monsour @bobmonsour.indieweb.social.ap.brid.gy · 14/10/2026
@chris You might find some useful stuff here: 11tybundle.dev/categories/webc/?hig…
11tybundle.dev
WebC
Posts in the 11ty Bundle with the category: WebC
101 1
Bob Monsour @bobmonsour.indieweb.social.ap.brid.gy · 07/10/2026
11ty Bundle Issue 96 #11ty @11ty 11tybundle.dev/blog/11ty-bundle-96
11tybundle.dev
CodePens on the blog, Hosting her own podcasts, Build a modern blog, And 9 other items of note
11ty Bundle Issue 96
000 0
Reposted by Bob Monsour
elle mundy @ap.exch.gr · 07/10/2026
new: now you can double tap to zoom in/out on images in the lightbox. (mobile only for now.) the code: github.com/exchgr/exch.gr-11ty/pull… to use it, tap any image in the gallery to reveal the lightbox, then double tap on the image to zoom in. do it again to zoom out, even if you […]
mastodon.world
Original post on mastodon.world
002 2
Bob Monsour @bobmonsour.indieweb.social.ap.brid.gy · 01/10/2026
And we're calling this October?!?
Temperature outlook in Pasadena, CA, with "Today" being October 1st
000 0
Bob Monsour @bobmonsour.indieweb.social.ap.brid.gy · 01/10/2026
11ty Bundle Issue 95 #11ty @11ty 11tybundle.dev/blog/11ty-bundle-95
11tybundle.dev
Letting the posts and sites speak for themselves
11ty Bundle Issue 95
011 1
Reposted by Bob Monsour
Brennan Kenneth Brown 👻 BOO! @brennan.social.lol.ap.brid.gy · 01/10/2026
For anybody interested, I published a #11ty #Eleventy theme/template/starter based on my plaintext blog: gitlab.com/brennankbrown/plaintext-…
gitlab.com
Brennan Kenneth Brown / plaintext-11ty-starter · GitLab
A starter theme for blogs inspired by plain-text release files (.nfo / README.txt). There's semantic HTML, but there's no colour, JavaScript, images, external requests, and only a single...
013 3
Reposted by Bob Monsour
Antoine @villapirorum.indieweb.social.ap.brid.gy · 30/09/2026
I just deployed my instance of Speedlify to profile all my website pages. speedlify.villepreux.net Awesome work by @zachleat ! Now I got dozen of pages to fix 😅🤦‍♂️ #buildawesome #11ty #speedlify #webdev
speedlify.villepreux.net
speedlify
Lighthouse lab metrics, Axe, and Chrome UX Report field data for a list of sites recorded and compared over time.
112 2
Bob Monsour @bobmonsour.indieweb.social.ap.brid.gy · 26/09/2026
Praying for my dear friends in the town where I spent my formative years, Margate City, NJ.
001 1
Bob Monsour @bobmonsour.indieweb.social.ap.brid.gy · 25/09/2026
RE: omfg.town/@dansinker/11733223657800… I read it, and perhaps you should too: dansinker.com/posts/2026-09-23-stop…
omfg.town
011 1
Bob Monsour @bobmonsour.indieweb.social.ap.brid.gy · 24/09/2026
11ty Bundle Issue 94 #11ty @11ty 11tybundle.dev/blog/11ty-bundle-94
11tybundle.dev
Topic relations, Highlight that code, Brennan builds faster, Self-inflicted debugging
11ty Bundle Issue 94
013 3
Reposted by Bob Monsour
Brennan Kenneth Brown 👻 BOO! @brennan.social.lol.ap.brid.gy · 22/09/2026
Static Site Generators for Beginners brennan.day/static-site-generators-… #blogging #jekyll #hugo #11ty #webdev #webdevelopment #javascript #css #html
brennan.day
Static Site Generators for Beginners
I've been writing technical tutorials on my website since I started it last November, but this thread asking about static site generators for beginners on 32-bit Café made me realize I've never made a proper tutorial regarding SSGs from the ground-up basics. This post initially began as a reply to that thread, but I realized I had enough to say to fill an entire blog post. I hope this is helpful to anybody who has been interested in static-site generators but has found trying them out to be difficult, obtuse, and with a lot of friction. I'm someone that grew up using SSGs, going from editing the HTML on my Tumblr straight to setting up a blog with Jekyll when I was a teenager around 15 years ago now. While I would say I'm knowledgeable, being able to communicate and articulate that knowledge (particularly to beginners) is another skill entirely, and one I want to cultivate more. Hopefully I do a good job with that here! ## Prerequisites Let me start off by saying that, if you're brand new to web development, I do **not** recommend beginning with a static-site generator. If you're making your first website (or ten), I really recommend writing out the HTML and CSS yourself—this removes a lot of the abstraction that occurs with SSGs. Nearly all SSGs assume you know the fundamentals of HTML, CSS, and sometimes JavaScript. They also assume some familiarity with programming concepts, the terminal, and usually version control such as Git. You certainly do not need to master all of these before making a site with an SSG, but knowing what is going on underneath the hood will make the inevitable errors much less mysterious. ### Free resources I would work through the resources below in the order I've listed, creating your own sites along the way: * **HTML:** HTML for People is a friendly introduction written for people with no previous coding or web experience. MDN's HTML learning module is a more technical reference for when you want to get to aspects like semantic elements and accessibility. * **CSS:** MDN's CSS styling and layout modules explain things like the box model and CSS layouts. If you prefer interactive exercises and projects, freeCodeCamp's Responsive Web Design course covers HTML, CSS, accessibility, and responsive design. (Responsive meaning mobile-friendly in most cases) * **JavaScript and web fundamentals:** MDN's JavaScript module is a good addition to its HTML and CSS lessons. And freeCodeCamp's JavaScript curriculum is another free, interactive option. * **Programming fundamentals:** CS50x is Harvard's free introduction to computer science. Computational thinking, algorithms, data structures, functions, variables, conditionals, and loops. You don't need to know all of this, but the first few weeks of the course would give you a good foundation. * **The terminal:** MIT's Missing Semester teaches the shell, command-line environments, editors, and debugging. Check out the introduction to the shell. * **Git and version control:** Pro Git is a free online book that starts with the command line and basic commits before moving on to branches, remotes, and hosting. Reading this on a Kobo during my commute to college was how I learned git myself. * **Markdown and YAML:** The Markdown Guide is good for seeing how symbols are used for writing in Markdown. For YAML, the official YAML 1.2 docs are more detailed than you need, but the introductory explanation is useful. * **Checking your work:** To see if your HTML has any errors, the W3C Nu HTML Checker is a good resource to detect any invalid markup. MDN has a "Learn Web Development" resource as a single place to learn HTML, CSS, JavaScript, and browser fundamentals. There are others, like the Odin Project, web.dev, w3schools, and more. Understand that you don't need to know everything. You're doing this as a hobby, it's fine to make mistakes or do things in unorthodox ways that guides don't recommend. The important thing is not to finish every course before starting—build tiny sites as you go along with what you learn. Each step will give you more competency and functionality to add to your projects. ## Definitions Next, before I jump into the history of static sites, I want to define some often-used terms you'll see when reading static-site documentation and guides, since a lot of this jargon is typically not defined well. Most developers will simply think you already know all of this stuff by default. ### The Web and the Generator **HTML (HyperText Markup Language)** is the base document of a webpage, it's a language of structure and semantics. Headings, paragraphs, links, images, lists, and stuff like that. HTML is not a programming language, so it doesn't make decisions or repeat actions by itself. <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>My First Page</title> </head> <body> <h1>Hello, world!</h1> <p>This page has a <a href="https://brennan.day">link</a> and a list:</p> <ul> <li>HTML gives a page its structure.</li> <li>There's no CSS yet, so this is all default styling.</li> </ul> </body> </html> Save that as `index.html`, open it in a browser, and you get a real page—see it live here. **CSS (Cascading Style Sheets)** changes how HTML is rendered. This is how you add specific and unique colours, spacing, fonts, responsive behaviour, etc. body { font-family: Georgia, serif; max-width: 35rem; margin: 2rem auto; padding: 0 1rem; background: #fff2ce; color: #02005d; } h1 { color: rebeccapurple; } Add that inside a `<style>` tag in the `<head>` and the exact same page now looks like this. **JavaScript** is the most commonly-used programming language in web browsers. It is frankly rather janky, but it's what we have to work with. It can add behaviour and interactivity to your site, but it is rarely ever necessary and can slow down and bloat a webpage. I personally recommend using it sparingly. const button = document.querySelector("#surprise"); button.addEventListener("click", () => { document.querySelector("h1").textContent = "JavaScript did this!"; }); With a `<button id="surprise">` added to the page, that script does this. An SSG can also use JavaScript, for example, to run its build process or its template code. In 11ty, you can even write an entire template as JavaScript: // hello.11ty.js module.exports = function () { return "<h1>Hello from JavaScript!</h1>"; }; * **Static** means that a server returns a file as-is, without generating a new page for every request (typically a user visiting the page). A static page can still contain JavaScript and can still be changed later, as “static” only describes how the page is delivered, not whether it is immutable or boring. * **Dynamic** means that something generates or changes the response at request time. A traditional content-management system might query a database and assemble a page whenever someone visits it. A store website would need to keep a database of inventory that changes based on when people add an item to their cart and purchase, for example. * **Static-site generator (SSG)** is a program that takes source files (like Markdown content, templates, configuration, and assets) and builds a rendered site of HTML, CSS, JavaScript, and image files from them that can be hosted as a static site. * **Build** is running the generator's command that turns those source files into output files. * **Source files** are the files you edit, such as Markdown posts, templates, stylesheets, and configuration. * **Output files** or **built files** are the finished files produced by the build, often placed in a folder such as `_site/`, `public/`, or `dist/`. * **Local server** is a web server running on your own computer. A development server lets you view the built site at a local address (like `localhost:8000`) and can rebuild it when you save a change to a source file. ### Configuration and Data * The **Configuration file** is a file containing site-wide settings—it can include things like a site's name, base URL, menus, output directory, RSS options, etc. Different SSGs use different filenames and formats, including `config.yml`, `hugo.toml`, and `eleventy.config.js`. * **YAML** (usually pronounced “yamel”) is a human-readable data language often used for configuration and front matter. It represents values such as strings, numbers, lists, and key-value mappings. Indentation in YAML is significant, so a stray space can cause a build error. * **Key-value pair** really just means here's two parts to each config option, such as `title: My post`. In YAML, a collection of these pairs is called a mapping. * **Parameter** or **option** is a setting passed to a command or configured in a file. For example, `--serve` is an option in a command shown later in this guide. Here's an 11ty site settings file (`src/_data/site.json`), where you edit the user-facing details of your site: { "name": "My Cool Blog", "description": "Where I write about whatever interests me.", "author": "Your Name", "url": "https://example.com", "language": "en" } Every key-value pair becomes a variable your templates can use: putting `{{ site.name }}` in a layout prints "My Cool Blog", so changing the name here updates it everywhere at once. This is one of the neat features of SSGs, and it means you only have to change the name in one place. Other SSGs put the same idea in `config.yml` (Jekyll) or `hugo.toml` (Hugo) instead. ### Templates and Content * A **Template** is a reusable file containing the structure of a page, with various placeholders. * **Layout** is a template for a larger page shape, containing all of the following: the document language declaration, `<head>`, header, main content area, and footer. * **Partial** is a smaller reusable fragment, such as a navigation bar, header, footer, or post metadata block. “Include” is the instruction that inserts one file or fragment into another. * **Templating language** is the syntax used to insert variables, loop over data, and make decisions inside templates. Liquid, Nunjucks, and Go templates are examples. * **Conditional** is a yes-or-no instruction in a template, such as “show this element only if the post has an image.” Here's a simple layout (`_includes/layouts/base.njk`, written in the Nunjucks templating language) that uses a few partials: <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>{{ title }} | {{ site.name }}</title> </head> <body> {% include "partials/header.njk" %} <main> {{ content | safe }} </main> {% include "partials/footer.njk" %} </body> </html> And the partials are fragments of HTML: <!-- partials/header.njk --> <header> <a href="/">{{ site.name }}</a> {% include "partials/nav.njk" %} </header> <!-- partials/nav.njk --> <nav> <a href="/">Home</a> <a href="/archive/">Archive</a> <a href="/about/">About</a> </nav> <!-- partials/footer.njk --> <footer> <p>© 2026 {{ site.author }}</p> </footer> When a post's front matter says `layout: base.njk`, 11ty wraps it in this template: `{{ content | safe }}` is where the rendered post body goes, and each `{% include %}` puts a partial in place. Edit the header once and every page on the site updates. This is the copy-paste problem SSGs solve. * A **Content file** is a source file, like a page or a post, typically written in Markdown. In SSGs this is often Markdown, but it may also be HTML, plain text, or another supported format. * **Markdown** is a rather well-known markup language that uses punctuation symbols to represent headings, links, lists, emphasis, and other document structure. A generator converts this into HTML. * **Front matter** is a small metadata block at the beginning of a content file, commonly enclosed by two lines of `---`. It can contain a title, date, tags, layout name, or draft status. * **Blog-aware** means that a generator is specifically built for posts. It can usually sort them by date, and can generate specific pages like an archive, tags page, and RSS feed automatically. * **Metadata** is information like a post's title, author, publication date, tags, description, canonical URL, or chosen layout. Here's a single 11ty blog post (`posts/my-first-post.md`) that uses all of the above: front matter metadata written as YAML key-value pairs, Markdown content, and a little templating language. --- title: My First Post date: 2026-09-22 tags: - posts - cats layout: post.njk draft: false --- Welcome to my blog! This paragraph is **Markdown**. This post is called "{{ title }}". {% if draft %} This sentence only appears while the post is a draft. {% endif %} The front matter between the two `---` lines is metadata 11ty reads before rendering. `layout` tells it which template to wrap the page in, `tags` makes it part of the `posts` collection, and `date` is how the blog-aware sorting knows where it belongs. Everything below the second `---` is the content file's body. ### Validation and Publishing * **Hosting** is the service or computer that stores the output files and makes them available on the internet. Hosting is separate from writing the site, and also separate from version control. * A **Backend** is the server-side code and infrastructure that runs behind a website. It handles authentication, forms, business logic, or database queries. A purely static site does not need a backend to serve its pages. * A **Database** is similar to a spreadsheet that software can query and update. A traditional dynamic blog stores posts, comments, and settings in a database. Anytime you see `SQL`, that's a database. * **FTP (File Transfer Protocol)** is the protocol used to copy files between computers, commonly from your computer to a web host. It is one way to publish a site. * **rsync** is a command-line program that synchronizes files between locations. It can copy just the files that were modified, which makes it useful for uploading a built site to a server. * **Link validation** is a nice quality-of-life feature that checks if any links go to missing pages. Some SSGs do this during the build, and others require a plugin or an external checker. ### Version Control * **Version control** is a system for recording changes to files over time so you can inspect history, compare versions, restore an earlier state, and collaborate with other people. * **Git** is one specific version-control program. It runs locally on your computer and can record the history of a project without requiring a hosting service. * A **Repository** (or **repo**) is a folder/project directory with a history managed by Git. * A **Commit** is a saved snapshot of changes in a repository, typically with a message describing the change. * **Remote** is another copy of a repository. Typically, there's a remote hosted version of the repo on Codeberg, GitHub, GitLab, or a server you control. * **Push** is a command that copies commits from your local repository to a remote. And **Pull** retrieves commits from a remote and incorporates them into your local repository. * **Git hosting** is a service that stores Git repositories and may provide extras such as issue tracking, code review, or automatic builds. This includes GitHub, GitLab, Codeberg, etc. * Git hosting is convenient, but it's good to remember that it is not the same thing as Git, and is not required to use Git. Here's what publishing a new post with git looks like in the terminal: git init # turn this folder into a repository (once) git add posts/new-post.md # stage the file for your next commit git commit -m "Add new post" # save a snapshot with a message git push # copy your commits to the remote ## A (Very) Brief History of Static Site Generators Now that we have all those definitions out of the way, let's actually talk about the context of static-site generators. SSGs didn't start with Jekyll. The idea of separating your writing from the code goes back to the mid-1990s. A really early example is HSC ("HTML Sucks Completely"), an HTML preprocessor Thomas Aglassinger released in 1996. The term "static site generator" wouldn't exist for another decade or so, but HSC already had includes, conditionals, and link validation. For most of the late 90s and 2000s, the mainstream answer to "how do I blog" wasn't static. It was hosted, dynamic services like Blogger, LiveJournal, and Open Diary. Or full-stack tools with databases and a backend, like WordPress. The one exception was Movable Type, a Perl-based platform Ben and Mena Trott built in 2001 that did something clever: every time you published through its web GUI, it rebuilt your blog into plain static HTML files behind the scenes. You weren't using the terminal, but the output was static. Movable Type was one of the first tools to bring the benefits of a static site for people who never typed a `build` command. Nanoc was built by Denis Defreyne in 2007 after finding all Ruby-based CMSes ran painfully slow on the 96MB VPS he was using. Nanoc introduced layouts, page metadata, Markdown support, and plugins. It was a year later, in December 2008, that GitHub co-founder Tom Preston-Werner released Jekyll, out of frustration with complex blogging engines like WordPress. Jekyll built on Nanoc's ideas and added two things: front matter (the YAML block of metadata at the top of every content file) and being "blog-aware" out of the box, meaning you could put Markdown files in a folder and it would turn them into a blog with no extra setup. GitHub launched GitHub Pages alongside Jekyll as free static hosting, and that combination is a large reason why Jekyll popularized SSGs for many, including myself. Everything since has really been reinvention and iteration on the same idea in different languages. Some prospered and some failed. Octopress (RIP) and Middleman iterated on SSGs in Ruby. Pelican and Hyde are Python-based and Laravel-based SSGs, respectively. In July 2013, Steve Francia released Hugo, written in Go and compiled to a single binary. This was far simpler relative to Jekyll: there was no entire Ruby environment you had to install, or gem versioning you needed to wrestle with, and Hugo is fast enough to render thousands of pages in seconds. Eleventy (11ty) was created by Zach Leatherman in late 2017 as an agnostic alternative to Jekyll, using JavaScript and NPM instead. Whereas Jekyll required you to use the Liquid language, 11ty lets you use: * HTML `*.html`, Markdown `*.md`, WebC `*.webc`, JavaScript `*.11ty.js`, Liquid `*.liquid`, Nunjucks `*.njk`, Handlebars `*.hbs`, Mustache `*.mustache`, EJS `*.ejs`, Haml `*.haml`, Pug `*.pug`, TypeScript `*.ts`, JSX `*.jsx`, MDX `*.mdx`, Sass `*.scss`, and even Custom `*.*` Jamstack.org has a full list of different SSGs, if you happen to have experience in a specific programming language and want to leverage that. Something important I want to note is that some of these generators haven't been updated in years. And guess what? That's actually usually fine! The "static" part of SSGs means there's no backend or database to hack. Another benefit is that security isn't something you need to worry about. Did your favourite SSG add genAI slop in the newest update? Just never update. Your SSG will continue working and building your site the way it is now indefinitely. Hurray! ## Why is git always recommended? Aside from programmers just finding git to be the status quo default, I think a lot of the assumptions regarding git are due to the fact that Jekyll, the first popular SSG, began as a GitHub-specific project. Using GitHub (or Codeberg, or GitLab, etc.) answers the question "where do the files live?" which is in the repository. Neocities/Nekoweb answer this by you uploading your files onto the site. When you use something like Codeberg Pages or GitLab Pages, a lot is happening underneath the hood, and every time you upload or edit a file, it _is_ being committed and pushed with git, you just aren't running the commands yourself manually via the terminal or GUI interface. If you're self-hosting, then the answer is just your own computer, somewhere like the `/var/www/html` folder if you're on Linux. If you have a Tildeverse account (which is yet another rabbit hole), then your files would live on the publicly-shared computer. Here's my Tilde.town site for example, where I use the command `rsync` to upload my local files from my computer to the tilde.town computer and they're hosted automatically. There are two different things git is actually doing here, and they're easy to conflate. * Version history (so you can undo a bad edit or see what changed and when) * Hosting (somewhere for the built files to actually live). You don't need git for either one. `rsync`, an FTP client, or dragging files into a browser upload window all work fine for hosting. And you can take care of backups for your own small personal site instead of worrying about version history. Git just happens to solve both problems at once and for free, which is why it often becomes the path of least resistance. ## Theory vs. Practice On paper: * You take Markdown files in a `posts/` folder * They're rendered with a template in a `layout/` folder * Which has modules of HTML in `partials/` like `header.html` and `footer.html` * And there's probably a `config.yml` file in the root or something similar where you can edit the parameters of the site, like the name, colours, etc. * That `config.yml` handles site-wide settings, but most SSGs also give each individual post its own small metadata block, usually called front matter, sitting at the top of the file between two lines of `---`. * That's where a single post's title, publish date, and tags live, separate from the global config, so the generator knows how to sort and label a page without you having to name it `"2024-03-14-my-post-title.md"`. In practice, it is far more complicated. The process of taking all of the above and outputting it to a rendered static site (say, into a `/_site` folder) requires a programming language to process it. Most popular SSGs _try_ to make this simple: you run a command like `hugo build` or `npx @11ty/eleventy --serve` in the terminal, and that will do the above. (That `--serve` flag will start a local server on your computer, and regenerate the site anytime you edit the source files, rather than just building once and quitting. That's what makes editing a static site feel nearly as immediate as editing a live page.) Platforms like Netlify (or the self-hosted Coolify) essentially have a restricted remote computer that will detect which SSG you're using and run the appropriate command automatically, and your `/_site` is then hosted at `yoursitename.netlify.app` similar to how you'd manually upload your own HTML files to Neocities and have your site hosted at `yoursitename.neocities.org` There are other platforms that do the same (that I would not personally recommend): Vercel, Cloudflare Pages, GitHub Pages, and surge.sh. But all of the above has _a lot_ of assumptions built-in: you've done everything perfectly, _and_ the programming language used to build the site installed correctly, _and_ you know how to use the terminal. This XKCD comic on average familiarity comes to mind. If you have a typo anywhere important that breaks something (which could be as innocuous as an extra comma somewhere) the entire thing is fragile enough to break either during the initialization or build process, and the error message is designed for the programming language, _not_ the SSG. Which means you'll get a very technical output. Here's an example of a failed Netlify build my site had recently simply because I had a trailing comma in the file that stores JSON. If you don't have the stubbornness that masochistic programmers (like me) have, it's very understandable that you see the above error and go "fuck that" and just handroll your HTML, or use a CMS, or just don't make a site at all. That last one is the most heartbreaking to me. ## My Starters/Themes The way I learned was by taking pre-made starters/themes others have made (as others in this thread have recommended) and tinkering with them. Then, I started to get proficient enough to make my own. If you want to get to know an SSG, I hope I can recommend these, as they have good-enough documentation/guides and are designed to be instructive for beginners: * **IndiePaper** is a Hugo starter I made with all the IndieWeb stuff built-in (microformats2, h-card, etc.), where you put your posts in the `/post` folder and edit the `hugo.toml` file to customize. * **11ty-Indie-Web-Blog-Starter** is an 11ty starter I made from the ground-up based on my own site, where you put your posts in the `/posts` folder and edit the `site.js` file to customize. * **Watery** is a Jekyll starter I made ages ago, where you put your posts in `/_posts` and edit the `_config.yml` file to customize. All of these themes are minimal and plain (and kinda ugly) because the actual CSS styling and design aspects are left to the user. ## Other (Simpler) Alternatives All the SSGs I used above are very popular ones, but there are many more relatively simple options out there. Like barf and bashblog and kiki. * **barf** (blogs are really fun) is a shell script by btxx that's only 170 lines. It's forked from Karl Bartel's blog.sh. There's no front matter and no templating, you just write Markdown files, run `make build`, and it produces a `build/` folder you rsync to your server. It generates valid RSS automatically, runs natively on Linux, macOS, and OpenBSD, and the stylesheet is four lines of CSS. You can read the README or view a live demo. * **bashblog** is a single ~1,000-line `bb.sh` script with zero dependencies, using base Unix utilities such as `date`, `grep`, `sed`, and `head`. Carlos Fenollosa built the first version in 2011, writing about it on his own blog, and it's still maintained today. You download `bb.sh`, put it in a public folder on your server, and run `./bb.sh post` to start writing. It handles drafts, tags, Markdown, and RSS out of the box, no installation step at all. If you want more features, there's a community fork called bashblog-ng. * **kiki** is by vga256 and self-describes as "a tiny homepage construction kit with a small footprint". It uses PHP rather than shell, and it can run as either a live dynamic site or generate a static one, and also double as a public wiki or (in preliminary form) a Gopher hole. It's shareware and free with a footer credit, or pay $15 CAD and get additional features. It's 1,500 lines of hand-written code, zero JavaScript and zero external dependencies. It's a great option if you have a host that only allows PHP and doesn't give shell access. And here are a few others: * **ssg** is Roman Zolotarev's POSIX-compliant shell script. It's the inspiration for several of the others on this list; there's a Python rewrite called pyssg. * **sw** is a minimal web framework written in C, and the fork **simple-static** strips it down further into what its README calls "the simplest static site generator I can think of." * **makesite.py** is a Python equivalent of barf and bashblog. It's under 130 lines and built by Sunaina Pai around the idea that "the code is the documentation." The idea being that there's nothing to configure that you can't just read and edit directly. None of these alternatives have anywhere near the features that Hugo or 11ty have, but as a result, they also don't have the complexity. Finally, you may also be interested in making a blog in Gemini:// which is an entirely different rabbit hole I've been getting into recently, and eliminates the need to generate anything at all. ## Conclusion I use SSGs because if I were to handroll the HTML for my site, then I'd have to copy-paste the header and footer for every page, and SSGs take care of that kind of thing. I go into more detail about this in my IndieWeb ladder article. To me, I don't care how you webweave or what method you use to get your work online, as long as you're participating and trying, I think you're succeeding! Give my WEBMASTER@ manifesto a read if you haven't already. Static-site generators are just one of many ways to get into webweaving, and I certainly hope you join us—however that looks.
026 6
Reposted by Bob Monsour
Jesse Vincent @s.ly · 16/09/2026
It kind of snuck up on me, but I'm going to be joining @timoreilly.bsky.social on Live With Tim tomorrow (Wednesday) morning at 9AM Pacific! You should tune in: www.oreilly.com/live/live-wi...
oreilly.com
Give Your Agents Superpowers: Jesse Vincent Live with Tim O'Reilly - Sep 16 - O'Reilly
What Claude's weights reveal about how it actually thinks
0233 23
Bob Monsour @bobmonsour.indieweb.social.ap.brid.gy · 03/09/2026
@sarajw Ouch! Feel better. 💐
000 0
Reposted by Bob Monsour
Matt Steele @mattdsteele.carhenge.club.ap.brid.gy · 31/08/2026
New post where I switch the blog to @davatron5000’s MicroLighter for syntax highlighting, with a custom @11ty plugin. Might this be the last syntax highlighter I use?? www.steele.blue/microlighter
steele.blue
MicroLighter is Living Span-Free In My <head>
013 3
Reposted by Bob Monsour
2 Spoopy 4 You @jcrabapple.dmv.community.ap.brid.gy · 28/08/2026
Since Robb Knight's Echofeed is shutting down soon, as you may have seen I built a similar open source RSS feed forwarder inspired by it. It's called Feedecho, as an homage to the original. github.com/jcrabapple/feedecho I am also going to pick up where Robb left off, and offer a paid […]
dmv.community
Original post on dmv.community
020 2
Bob Monsour @bobmonsour.indieweb.social.ap.brid.gy · 25/08/2026
I've gotta say that 71 feels an awful lot like 70, which felt an awful lot like 69, which felt an...well, you get the idea.
000 0
Bob Monsour @bobmonsour.indieweb.social.ap.brid.gy · 24/08/2026
RE: mastodon.social/@ChrisAintMarchin/1… More like this, please.
000 0
Bob Monsour @bobmonsour.indieweb.social.ap.brid.gy · 16/08/2026
@sarajw It’s the first one I’ve seen. I’ll check out some more of them.
000 0
Bob Monsour @bobmonsour.indieweb.social.ap.brid.gy · 16/08/2026
@sarajw Agree. Thanks for sharing it. The story about Korea is incredible. en.wikipedia.org/wiki/Gold-collecti…
en.wikipedia.org
Gold-collecting campaign - Wikipedia
101 1
Bob Monsour @bobmonsour.indieweb.social.ap.brid.gy · 13/08/2026
@ricmac You'll never guess what I would suggest…yes, @11ty.
000 0
Reposted by Bob Monsour
Brennan Kenneth Brown 👻 BOO! @brennan.social.lol.ap.brid.gy · 12/08/2026
I've completely overhauled my IndieWeb 11ty Starter to make it simpler and more accessible for people getting into JAMstack and the IndieWeb. It now uses #11ty / #Eleventy 3.x with a modular config structure, chota.css instead of Tailwind, and Pagefind for fast, serverless search. The starter […]
social.lol
Original post on social.lol
013 3
Bob Monsour @bobmonsour.indieweb.social.ap.brid.gy · 10/08/2026
Not only was I wrong about which power of 2 was 32, it turns out that we've been married for 33 years, not 32.
000 0
Bob Monsour @bobmonsour.indieweb.social.ap.brid.gy · 07/08/2026
So no one caught my error that it is 2^5 =32 32, not 2^6
100 1
Bob Monsour @bobmonsour.indieweb.social.ap.brid.gy · 07/08/2026
Celebrating 2^6 = 32 years of marriage. The power of two, the two of us. Happy Friday everbody.
110 1
Reposted by Bob Monsour
MrAlanCooper @mralancooper.hachyderm.io.ap.brid.gy · 05/08/2026
There are a lot of heated words being shouted about trump's war against Iran. Few of them seem to adequately articulate the underlying problem. trump is in the process of bankrupting the USA. He's stealing as much as he can and burning up all that remains in a Middle Eastern bonfire. Warfare is […]
hachyderm.io
Original post on hachyderm.io
003 3
Bob Monsour @bobmonsour.indieweb.social.ap.brid.gy · 04/08/2026
But if you've been following along via RSS, you haven't missed anything.
001 1
Bob Monsour @bobmonsour.indieweb.social.ap.brid.gy · 04/08/2026
I'm sitting on 9 blog posts 29 new sites and 3 releases of content for the next issue of the 11ty Bundle blog/newsletter. I'll try to get it out this week. Moving has been consuming my time. #11ty @11ty
100 1
Bob Monsour @bobmonsour.indieweb.social.ap.brid.gy · 02/08/2026
Seems that Gmail no longer automatically (or even offers to) add a flight reservation confirmation to your Google Calendar without signing up for Gemini. Lame.
100 1
Bob Monsour @bobmonsour.indieweb.social.ap.brid.gy · 30/07/2026
“I need a single canonical Eleventy build, two real hostnames, one xmit team, and a workflow boring enough that I will understand it six months from now.” @adjb www.adamdjbrett.com/blog/two-domain…
adamdjbrett.com
There is a very particular kind of joy that comes from solving a web problem whose final answer is smaller than the problem felt. I wanted the American Indian Law Alliance website to live at both aila.ngo and `aila.ong`. The pairing matters: `.ngo` is the primary address, while `.ong` is its parallel form. I did not want the second domain to bounce visitors to the first. If somebody requests `/give/`, a blog post, an image, a PDF, or any other site resource from either hostname, that hostname should serve the resource itself. This sounds ordinary until the requirements are stated precisely. It is not a redirect rule. It is not an alias that only works for the homepage. It is the entire generated site—hundreds of pages and a large document archive—available under two fully qualified domains. When I finally had it working, I felt euphoric. Not because the solution was elaborate, but because it was not. ## One canonical build # The site is built with Eleventy. Eleventy writes the finished static site to `dist`, so there is no application server and no runtime routing layer to duplicate. The first important decision was to build only once. I set the production URL to the primary domain: - name: Build Eleventy site run: npm run build env: URL: https://aila.ngo That keeps canonical links, Open Graph URLs, feeds, and the sitemap anchored to `aila.ngo`. Search engines get one authoritative address even though human beings can use either domain. The parallel domain serves the same HTML, but the metadata continues to identify the primary. This distinction cleared up much of my confusion: “available at two domains” does not have to mean “build two versions.” ## Let xmit launch the same bundle twice # xmit is unusually well suited to this because it treats a static deployment as a content-addressed bundle. It hashes the files and uploads only content it does not already have. My site includes a substantial collection of PDFs, images, fonts, Pagefind indexes, and ordinary HTML. Uploading the same unchanged bytes twice would be absurd. xmit recognizes that they are the same bytes. The domain-to-team syntax is also wonderfully small. Team 389 is written after the hostname: xmit "aila.ngo@389" dist xmit "aila.ong@389" dist That is the heart of the solution. Both commands launch the complete `dist` directory. Neither command contains a path list because none is needed. `/give/` was my first test, but it is not a special case. Every post, page, image, stylesheet, font, feed, search index, and document goes along with it. The production workflow adds retries because an 800-plus-megabyte site should not fail permanently over one transient network error: env: XMIT_PRIMARY_SITE: aila.ngo XMIT_PARALLEL_SITE: aila.ong steps: - name: Deploy to xmit env: XMIT_KEY: ${{ secrets.XMIT_KEY }} run: | for site in "$XMIT_PRIMARY_SITE" "$XMIT_PARALLEL_SITE"; do deployed=false for attempt in 1 2 3; do if ./node_modules/.bin/xmit "$site@389" dist; then deployed=true break fi sleep $((attempt * 15)) done [ "$deployed" = true ] || exit 1 done The DNS records for both domains point to xmit, and xmit serves each requested hostname directly. A request to `https://aila.ong/give/` stays on `aila.ong`; it is not sent to `aila.ngo`. Yet both responses come from one Eleventy build. ## The speed came from doing less # The other satisfying part was making repeat deployments faster without inventing a new build system. Eleventy’s image pipeline already maintains a cache, so GitHub Actions only needed to preserve it: - uses: actions/cache@v6 with: path: .cache/@11ty/img key: eleventy-images-${{ runner.os }}-${{ hashFiles('package-lock.json') }} restore-keys: eleventy-images-${{ runner.os }}- That cache is about 53 MB. Restoring it avoids regenerating responsive images on every clean runner. Pagefind takes less than a second; it was never the bottleneck. Dependency installation was already cached by `setup-node`. xmit already avoids resending unchanged content. The fast solution was to let each tool do the job it already knew how to do. There are more sophisticated architectures for multi-domain publishing. I do not need one. I need a single canonical Eleventy build, two real hostnames, one xmit team, and a workflow boring enough that I will understand it six months from now. That is what produced the joy: not merely seeing both domains resolve, but realizing that the correct model had been sitting in front of me all along. Build the site once. Name the primary. Launch the same artifact wherever it belongs.
010 1
Bob Monsour @bobmonsour.indieweb.social.ap.brid.gy · 30/07/2026
When I asked Claude Code for an expansive change to a naming convention for an app that we've built, I never expected this as its first response: "Let me survey the actual blast radius before I describe the plan — counts matter here.”
210 2
Bob Monsour @bobmonsour.indieweb.social.ap.brid.gy · 27/07/2026
@ricmac Congratulations!
000 0
Reposted by Bob Monsour
SimonCox @simoncox.com · 26/07/2026
Made some changes to my sites framework which prompted some other changes and now I have secondary content links that are topical and it looks like it works well for some people who want to binge on a topic! #11ty #seo www.simoncox.com/short-articl...
simoncox.com
Filtered Topic Supplementary Posts
In a bout of inspiration this week I changed some of the framework on this site with unexpected results.
151 5
Bob Monsour @bobmonsour.indieweb.social.ap.brid.gy · 21/07/2026
Evening clouds over Caltech
Evening clouds over Caltech
000 0
Bob Monsour @bobmonsour.indieweb.social.ap.brid.gy · 19/07/2026
Built with Eleventy: From the 11ty Bundle Showcase Built with Eleventy: The Tampa Monitor @11ty.dev @michaelbishop.me #11ty @11ty 11tybundle.dev/showcase/tampamonito…
11tybundle.dev
The Tampa Monitor
Independent civic journalism for Tampa and Hillsborough County — City Council coverage, the budget, land use, and the data tools behind it.
001 1
Reposted by Bob Monsour
Grepehu | tabledown.net @grepehu.dice.camp.ap.brid.gy · 15/07/2026
I needed a doc builder that was simple because it was going to be used internally only, and I noticed most static websites themes, starter projects and even standalone doc builder had to many dependencies, I wanted something simple, so I decided to create one. I built from scratch simple […]
dice.camp
Original post on dice.camp
021 2
Bob Monsour @bobmonsour.indieweb.social.ap.brid.gy · 11/07/2026
A modern convenience at the Oakland airport
Telephone hanging by a wire
000 0
Bob Monsour @bobmonsour.indieweb.social.ap.brid.gy · 08/07/2026
11ty Bundle Issue 93 #11ty @11ty 11tybundle.dev/blog/11ty-bundle-93
11tybundle.dev
Build Awesome (11ty) v4.0.0.0 alphas, One markdown file to multiple output files, Adam has caught fire, Brennan also remains prolific, Using AI to diagnose performance issues
11ty Bundle Issue 93
001 1
Bob Monsour @bobmonsour.indieweb.social.ap.brid.gy · 06/07/2026
From the 11ty Bundle Showcase Built with Eleventy: Arau #11ty @11ty @araubrunch@tiktok.com 11tybundle.dev/showcase/araubrunch-…
11tybundle.dev
Arau
Argentine flavours, Australian spirit, Barcelona heart. Argentine-Australian inspired brunch and specialty coffee in the Eixample, Barcelona.
000 0
Bob Monsour @bobmonsour.indieweb.social.ap.brid.gy · 06/07/2026
From the 11ty Bundle Showcase Built with Eleventy: Christa Dalmazio #11ty @11ty 11tybundle.dev/showcase/christadalm…
11tybundle.dev
Christa Dalmazio
Christa Dalmazio is a classical and sacred musician and a Doctor of Musical Arts of the Manhattan School of Music. A soprano and conductor, her work centers on sacred music and the music of the Mass.
010 1
Bob Monsour @bobmonsour.indieweb.social.ap.brid.gy · 06/07/2026
From the 11ty Bundle Showcase Built with Eleventy: Cole’s Capital Group #11ty @11ty 11tybundle.dev/showcase/colescapita…
11tybundle.dev
Cole’s Capital Group
Cole's Capital Group is a privately held real estate investment and management company building lasting value across New York's Capital Region.
000 0
Reposted by Bob Monsour
Charles Keener @charleskeener.bsky.social · 05/07/2026
33817 38
Bob Monsour @bobmonsour.indieweb.social.ap.brid.gy · 05/07/2026
While hard to believe, looks like it's true. pasadenanow.com/main/man-in-wheelch…
pasadenanow.com
000 0
Bob Monsour @bobmonsour.indieweb.social.ap.brid.gy · 30/06/2026
It is NOT anti-semitic to know that this is wrong. www.haaretz.com/west-bank/2026-06-3…
haaretz.com
103 nails on the map: How Israel's government is burying the two-state solution
During its term, Israel's government has approved the establishment and legalization of dozens of strategically placed settlements across the West Bank. The goal: to create irreversible facts on the ground that could make any future political settlement nearly impossible. Even if a future coalition tries to reverse course, experts say, it will be extremely difficult to do so
001 1
Bob Monsour @bobmonsour.indieweb.social.ap.brid.gy · 29/06/2026
@WeirdWriter Maybe this? It has a link to the source for it. rknight.me/blog/my-blogging-workflow
rknight.me
Heiji asked what my blogging workflow is and I thought not only is it an interesting idea for a post, but also can serve as a blueprint for how I want my new CMS to work. ### Post Types I have four types of posts on my site: * Blog posts - titled, usually long-form, posts like this one * Links - Links to interesting articles usually with a quote and comment * Almanac - My media blog for books, movies, tv shows, and games * Notes - This one is new and I'm not using it yet but it's going to be for shorter, title-less micro blogging There's also the changelog but that's updated much less. For all of these, because the site uses Eleventy, I have to commit and push to GitHub. #### Blog Posts I usually write a draft in Obsidian either on my phone or Mac then, if I want someone to eyeball it and give feedback, I'll post the draft to a private paste on paste.lol. Once I'm happy with it I'll create a new post in my site's repository, paste over the content, add an excerpt, and run Eleventy locally to check everything looks okay. Then I commit and push it to GitHub. To create a new post on my Mac, I use the CLI tool I made which handles all this. I run `npm run cli` in the terminal, choose "Create a new post", set the title and tags, and the CLI creates a new file in the right place. It also handles adding new games and projects, as well as fetching my Lego and comics collections when I've added new things. You can see the code for the CLI here. So how do I create posts when I'm not at my Mac? I don't. This is why I need a CMS. #### Links These are harder to do manually because I like to get a lot of metadata for a link post. As an example here's the contents of the latest link post file. I get the authors name, RSS feed, and Mastodon handle as well as the link title and URL: --- title: "Would You Recommend Us to Your Friends?" permalink: /links/would-you-recommend-us-to-your-friends/index.html link: https://starbreaker.org/blog/rants/would-you-recommend-us-to-your-friends/index.html date: 2024-05-08T13:48:10.335Z author: name: Starbreaker web: https://starbreaker.org feed: https://starbreaker.org/feeds/everything.xml mastodon: https://social.lol/@starbreaker --- > Whether or not I would recommend your business is none of your business. Who the fuck are you to even ask this question of your customers? Amen. Fuck right off with all this. I have a bookmarklet that I use which collects all this data and redirects me to a new file page on GitHub. To build this bookmarklet, I use this script to bundle them and pop them on the bookmarklets page. Once I'm on the GitHub editor I can edit or add my comments then commit the file. #### Almanac For movies, I use Letterboxd and the GitHub service on EchoFeed to take new reviews and add a new post to the GitHub repository. The echo config looks like this: --- title: "{{ custom.letterboxd.filmTitle }}" year: {{ custom.letterboxd.filmYear }} date: {{ datetime:iso_full }} permalink: /almanac/movies/{{ date:iso }}-{{ title:slug }}/index.html link: {{ link }} --- {{ content:plain }} And you can see an example of a post made this way here. For TV, games, and books this is a manual process. I create a new post in the correct folder (in this case, `src/posts/almanac/2024`), add the metadata I need and commit it. There's no media lookup, or pulling of the cover/poster, which I would like to include - a handy CMS feature I'll be building. #### Notes The plan for this one, and one of the big reasons I want a proper CMS, is to replace a lot of my posting directly onto Mastodon with actual posts on my site. I did do a test post and it worked so that's a good start. ### Cross-Posting You might have noticed I didn't mention cross-posting for the last three post types and that's because they all use the same system: a custom JSON feed extension and EchoFeed. For blog posts, I always post these myself to Mastodon. If you look at the links JSON feed you'll see an object for each post that looks like this: "_knightposse": { "about": "https://rknight.me/about/colophon/", "text": "Would You Recommend Us to Your Friends? by @starbreaker@social.lol https://starbreaker.org/blog/rants/would-you-recommend-us-to-your-friends/index.html\n\n\"Whether or not I would recommend your business is none of your business. Who the fuck are you to even ask this question of your customers?\"\n\nAmen. Fuck right off with all this.\n\n📌 https://rknight.me/links/would-you-recommend-us-to-your-friends/", "tags": [], }, This allows me, in EchoFeed, to use `{{ custom._knightposse.text }}` in my config and control what gets posted from my site. For link posts, I mention the author's Mastodon handle if I have it. If there's a blockquote in the post, I'll convert it to have quotes around it when it goes to Mastodon. All of this is done in the `makeTootText` filter of my Eleventy config. One of the hard parts of cross-posting to Mastodon (or Bluesky, or Twitter) is the character limits. Mastodon, by default, limits to 500 characters so I needed to find a way to handle that. If you want to look the code in full, you can see that here in my filters file. The core of it is checking the length of the output and if it's two long, falling back to shorter versions. For link posts, first I check if all the text (title, mention, quotes, comments) can fit in the limit. If it doesn't, I fall back to just the title, mention, and quote. Finally if that doesn't work, I fall back to just the title, mention, and link - which is unlikely to go over the limit unless for some reason I use a _very_ long title. if (mastodonCount.getMastodonLength(contentWithAllText).length <= 500) { content = contentWithAllText } else if (mastodonCount.getMastodonLength(contentWithFirstQuote).length <= 500) { content = contentWithFirstQuote } else { content = `${content}\n\n📌 ${permalink}` } return content To find out the length, you can't just check the length of the string - links are always counted as 23 characters and only the first part of the username is counted `@robb`, the domain is ignored (`@social.lol`). That is what `getMastodonLength` is doing with some wild regex I borrowed directly from Mastodon itself. As an example, the previous link post I mentioned above gets posted to Mastodon like this: > ⭐ Would You Recommend Us to Your Friends? by @starbreaker https://starbreaker.org/blog/rants/would-you-recommend-us-to-your-friends/index.html > > "Whether or not I would recommend your business is none of your business. Who the fuck are you to even ask this question of your customers?" > > Amen. Fuck right off with all this. > > 📌 https://rknight.me/links/would-you-recommend-us-to-your-friends/ ### The CMS The CMS that I'm imagining would ideally allow me to do all of this stuff from anywhere I have internet access. For links, automatically pull in the author details. For almanac, have media data lookup. For blog posts and notes, the ability to post from anywhere. Load my following list so I can mention people on Mastodon. I guess I should start building it really.
000 0
Bob Monsour @bobmonsour.indieweb.social.ap.brid.gy · 28/06/2026
RE: hcommons.social/@adjb/1168264008130… “It is why I care about plain text, low-friction builds, stable URLs, HTML-first publishing, search that does not depend on a cloud black box, and keeping complexity where complexity earns its keep.”
hcommons.social
102 2