返回资讯中心
外部精选
软件工程
#开发者实时流

Static Site Generators for Beginners

Vintage Victorian style retro typewriter engraving. Original from the British Library. | Rawpixel (edited by the author)

Hacker News 最新ziofill2026/10/28 · 今天30 分钟阅读

以下正文同步自 Hacker News 最新,版权归原站所有,已转换为易读排版。

Vintage Victorian style retro typewriter engraving. Original from the British Library. | Rawpixel (edited by the author)

Place of publication: Calgary, Alberta, Canada

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!

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.

I would work through the resources below in the order I've listed, creating your own sites along the way:

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.

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.

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.

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>&copy; 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.

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.

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 rele

正文由 探How 从来源站点 RSS 同步,内容未经改写;遇到排版缺失或需要图片、视频时请以原文为准。

打开原文
去社区讨论 →