Personal site built with Eleventy and published to GitHub Pages by GitHub Actions on every push to main.
You need Node.js 20 or newer.
npm install # once, after cloning
npm start # preview at http://localhost:8080, reloads on save
npm run build # build the published site into _site/Run npm run build before opening a pull request. If it fails, the site won't publish.
| Path | What it is |
|---|---|
src/index.njk |
Home page |
src/blog/index.njk |
Blog page (lists posts automatically) |
src/blog/posts/ |
Blog posts, one Markdown file each |
src/_data/authors.json |
Author names, bios, emails and photos |
src/_includes/layouts/base.njk |
Shared page wrapper: head, analytics, navigation, footer |
src/_includes/layouts/post.njk |
Blog post layout: title, lede, byline, author bio |
src/css/style.css |
All styles |
src/img/ |
Images |
eleventy.config.js |
Build settings, date filters, sidebar/callout shortcodes |
Everything under src/ is the site. _site/ is generated output and isn't committed.
The blog is currently off: the site is a single page, with no menu, and nothing under src/blog/ is published. To turn it on, set BLOG_ENABLED to true at the top of eleventy.config.js. That publishes the blog page and posts and shows the Home / Blog menu on every page.
-
Copy
src/blog/posts/example-post.mdto a new file in the same folder. The file name becomes the address, e.g.my-topic.md→/blog/my-topic/. Use lowercase words separated by hyphens. -
Fill in the details at the top:
--- title: My Post Title lede: One or two sentences summarizing the post. Also shown on the blog page. author: drew # a key from src/_data/authors.json date: 2026-10-01 # YYYY-MM-DD; sets the order on the blog page draft: true # remove to publish ---
-
Write paragraphs in Markdown, separated by blank lines.
-
Add boxes where needed. The text inside can use Markdown:
{% sidebar "Sidebar Title" %} Floats beside the text on wide screens, full width on phones. {% endsidebar %} {% callout "Callout Title" %} A highlighted, full-width box for key points. {% endcallout %} -
Preview with
npm start. Drafts appear in the preview but aren't published. Removedraft: truewhen the post is ready.
Add an entry to src/_data/authors.json. The key (e.g. "jane") is what posts use for author:.
"jane": {
"name": "Jane Doe",
"bio": "is a ... (a few sentences, starting after the name)",
"email": "jdoe - at - example - dot - org",
"photo": "/img/authors/jane.jpg"
}- Write the bio to follow the name: the page shows Jane Doe followed by the bio text.
- Write emails in the spelled-out form above so spam bots can't collect them.
- Use a square photo; it's shown as a small circle.
/img/author-placeholder.svgworks until a real photo is available.
-
Create a Markdown file in
src/, e.g.src/talks.md. The file name becomes the address:/talks/. -
Start it with:
--- layout: layouts/base.njk title: Talks ---
-
Write the content in Markdown. HTML also works when you need more control.
-
To link it from the navigation, add a line to the
<nav>insrc/_includes/layouts/base.njk, following the Home and Blog links.
- Put images in
src/img/(or a subfolder) and reference them with a leading slash:in Markdown, or<img src="/img/my-photo.jpg" alt="Description">in HTML. - Always include alt text describing the image.
- Keep images reasonably small (under ~500 KB); resize large photos before adding them.
- To host other files such as PDFs, create a folder under
src/and add it toeleventy.config.jswitheleventyConfig.addPassthroughCopy("src/your-folder");.
All styles are in src/css/style.css. Page content is centered and capped at 70% of the window width, widening to 90% on screens under 600px. Check any style change at both desktop and phone widths.
- Create a branch from
main. - Make your changes and check them with
npm startandnpm run build. - Open a pull request into
main. - Once it's merged, GitHub Actions rebuilds and publishes the site. You can follow progress in the repo's Actions tab. Changes usually go live within a couple of minutes.