Only show guides for your app
Write posts in Markdown, run Eleventy to turn them into a folder of static HTML, and serve that on the static-site setup. Covers the verified build and the honest choice between building locally and building on a server.
A blog is mostly text, so you don't want a database or a running app behind it — you want plain HTML that a web server can hand out instantly. Eleventy (11ty) is a static-site generator: you write posts in Markdown, run one command, and it produces a folder of finished HTML pages. This guide builds that blog, then covers the part most tutorials skip: where the build runs, and how the output gets onto Falix.
| At a glance | |
|---|---|
| You're building | A Markdown blog compiled to static HTML by Eleventy |
| You need | Node to run the build; the static-site setup to serve the output |
| Plan | Any plan |
| Time | About forty minutes |
New to static hosting? Read Host a static website first — it's where the finished pages end up.
| Piece | File |
|---|---|
| Build config | .eleventy.js — input/output folders, a date filter |
| Layout | src/_includes/base.njk — the HTML wrapper every page shares |
| Home page | src/index.njk — lists your posts |
| Posts | src/posts/*.md — one Markdown file per post |
| Output | _site/ — the finished static site Eleventy generates |
package.json — Eleventy as a dev dependency, plus a build script:
{
"name": "blog-eleventy",
"version": "1.0.0",
"private": true,
"scripts": {
"build": "eleventy"
},
"devDependencies": {
"@11ty/eleventy": "^3.0.0"
}
}
.eleventy.js — the configuration:
module.exports = function (eleventyConfig) {
// Copy the stylesheet straight through to the output folder.
eleventyConfig.addPassthroughCopy("src/style.css");
// A tiny date filter so templates can print "2026-07-01".
eleventyConfig.addFilter("date", (d) => new Date(d).toISOString().slice(0, 10));
return {
dir: { input: "src", includes: "_includes", output: "_site" },
markdownTemplateEngine: "njk",
htmlTemplateEngine: "njk",
};
};
src/_includes/base.njk — the shared page wrapper:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{{ title }}</title>
<link rel="stylesheet" href="/style.css">
</head>
<body>
<header><a href="/">My Blog</a></header>
<main>{{ content | safe }}</main>
</body>
</html>
src/posts/posts.json — directory data that gives every post the layout and a shared tag (so they form a collection):
{
"layout": "base.njk",
"tags": "post"
}
src/index.njk — the home page, listing posts newest-first:
---
layout: base.njk
title: My Blog
---
<h1>My Blog</h1>
<ul>
{% for post in collections.post | reverse %}
<li>
<a href="{{ post.url }}">{{ post.data.title }}</a>
<small>{{ post.date | date }}</small>
</li>
{% endfor %}
</ul>
src/posts/hello-world.md — a post is just Markdown with a title and date:
---
title: Hello, world
date: 2026-07-01
---
# Hello, world
This is my first post, written in **Markdown**. Eleventy turns this file into
`/posts/hello-world/index.html` when it builds.
Add a src/style.css for looks, and drop in more .md files to add posts.
Eleventy runs on Node, so build it where Node lives — your own computer, or a Node server (more on that below). In the project folder:
npm install
npx @11ty/eleventy
You'll see it write the pages:
[11ty] Writing ./_site/index.html from ./src/index.njk
[11ty] Writing ./_site/posts/hello-world/index.html from ./src/posts/hello-world.md
[11ty] Copied 1 Wrote 3 files in 0.05 seconds (v3.1.6)
The _site/ folder now holds a complete static site — a home page that lists your posts, one HTML page per post, and your CSS copied across. That folder is everything you deploy.
🎯 Good to know: Everything in
_site/is plain HTML — no Node, no Eleventy, nothing running. Whatever serves it just needs to hand out files, which is exactly what the static-site setup does.
Here's the honest part: Eleventy is a build tool (needs Node) and the static-site setup is a web server (nginx, no Node). They're two different jobs, so you have a choice about where the build happens.
npx @11ty/eleventy on your computer._site/ into that server's public/ folder — drag them in the File Manager, or push over SFTP.This is the simplest and most reliable option: nginx serves finished files, there's no build to break on the server, and nothing of yours has to keep running.
Let Falix rebuild on every push, using Git deploy with a build step:
Connect your repo on the Git page and add a post-deploy command npx @11ty/eleventy (see Build steps).
The catch: the command runs where your server's application can run it. Eleventy needs Node, which the PHP Web Server (static-site) image doesn't have — so to build on the server you run it on a Node.js application and serve _site/ yourself with a tiny static server:
const express = require('express');
const app = express();
app.use(express.static('_site'));
const PORT = process.env.SERVER_PORT || 8080;
app.listen(PORT, '0.0.0.0', () => console.log(`Listening on port ${PORT}`));
Point the Main file at this index.js, add express to package.json, and set the build script to run on deploy. Now a git push rebuilds and serves in one step — at the cost of running a Node process instead of nginx.
| Path A: build locally | Path B: build on server | |
|---|---|---|
| Runs on | static-site (nginx) | Node.js application |
| Server needs Node | no | yes |
| Rebuild on push | manual re-upload | automatic via Git |
| Best for | simplest, most reliable | frequent posts, hands-off |
💡 Tip: Most blogs post rarely, so Path A is usually the right call — build when you write, upload once. Reach for Path B when you're pushing often and want it automated.
base.njk and style.css; Eleventy stays out of your way.feed.xml from your posts collection so readers can subscribe.draft: true and filter it out of the collection until it's ready.Everything past the Falix layer is standard Eleventy — the official docs at 11ty.dev cover layouts, collections, data, and plugins in full.
eleventy: not found — you didn't npm install first, or you're not in the project folder. Install, then use npx @11ty/eleventy.post collection. Check src/posts/posts.json sets "tags": "post" and your posts are in src/posts/.posts.json above assigns base.njk to everything in the folder; make sure the file is there.index.html directly (upload the contents of _site/, not the _site folder itself). See Host a static website.