Skip to content

The official website of the Automerge project, with docs, references, community links, and more!

License

Notifications You must be signed in to change notification settings

automerge/automerge.github.io

Repository files navigation

The Automerge Website

This repository holds the Automerge website, including all the docs, blog posts, and other site content, the templates that give pages their structure and styling, and a custom build system that weaves it all together.

We welcome all contributions. If you see any mistakes or glitches on the website, or have any trouble building the site locally, please file an issue or open a pull request. Thank you.



Getting Started

First:

  • Clone the repo and run npm install (or yarn, or pnpm… whatever you use, it'll probably work).

Henceforth:

  • Run site to build the website and spin up a live-reloading dev server.
  • Run site help to see other available commands.

If site doesn't work, use ./site instead (or add . to your $PATH)



Documentation



Overview

Here's the folder structure:

  • content — html and markdown files for every page, plus a few lightweight assets; see pages
  • demo — source files for the interactive demo on the home page
  • fonts — uncompressed source files for fonts used on the site; see fonts
  • public — automatically generated when building the site
  • system — the build system source code; see system
  • template — html files that define different types of page on the site; see templates
  • Redirects.txt — Cool URIs don't change; see redirects

This site is powered by our own custom build system, which we can adapt and extend as our needs change.

The build system takes HTML and Markdown files in the content folder, parses and transforms them with rules defined in system, combines the result with various templates in template, and finally saves the fully-assembled page to public.

In short, the content folder should feel like an FTP server. You put stuff in there, and it shows up on the website. The file path becomes the URL. There's more, of course — macros and templates and other behaviour that we'll get to in a second. But all that fanciness is opt-in. If you stick to plain HTML and simple assets, /content feels just like FTP.



Pages

We're going to talk a lot about pages — so what's a page? It's an HTML or Markdown file that lives in the content folder, with some frontmatter explaining what the page is and how it should be processed.

If you make an HTML file /content/pens/index.html, the build script copies it over to /public/pens/index.html, and it becomes a web page with the URL /pens/index.html.

If you make a Markdown file /content/rams/index.md, the build system will convert it to HTML, copy it to public, and it'll end up with the URL /rams/index.html.

Clean URLs

Many web servers have a nice feature: if a page is named index.html, you can omit that part of the URL. So the above pages can also be accessed at /pens and /rams. Those are clean URLs.

To make the most of these clean URLs, the build system has one trick: pages are renamed from name.html to /name/index.html, so the URL can be /name.

Thus, a page with the URL /eraser/head will be generated by exactly one of these files:

  • /content/eraser/head.md
  • /content/eraser/head.html
  • /content/eraser/head/index.md
  • /content/eraser/head/index.html

Use whichever file naming you like. It's fine to mix and match. Though for pages with static assets, it's recommended to use one of the latter two forms so you have a natural place to put those assets. And if there's ever a conflict (where two files would have the same URL), you'll see a helpful error message.


Frontmatter

At the top of every page is the frontmatter section — properties that control how the page is processed by the build system. The frontmatter section begins and ends with ---, and uses a key: value # comment syntax that looks like YAML but is much simpler.

Here's an example of what frontmatter looks like:

---
title: Automerge
styles: /index/index.css, /index/demo.css
scripts: /index/dithering.js
template: landing
---

Frontmatter is optional

All the fanciness of the build system is opt-in. Frontmatter is the primary way for a page to opt-in to special processing.

  • For an HTML file with no frontmatter, no processing is applied (including the aforementioned clean-URL renaming).
  • All markdown files in /content get processing special whether they have frontmatter or not.

Template

The most crucial piece of frontmatter is template, which specifies what kind of page this is. The build system will inject the page's content into the matching template HTML file from /template. See the Templates section for more.

Publish

Another important piece of frontmatter is publish. It's true by default, which means the page will be included when building the website. You can set it to draft, which means the page won't be included on automerge.org, but will be included in local dev builds. Or you can set it to false to completely exclude the page from all builds.

If a non-draft page links to a draft, you'll see a helpful warning.

For most CLI commands, you can specify --no-draft if you don't want drafts to be included. But, for site build, drafts are excluded by default, and you must use --draft to include them.

Date

If a page is given a date, it'll be included in RSS feeds. The date must be in YYYY-MM-DD format.

Others

  • title will be used for <title> and for RSS.
  • description will be used for OG and RSS. Can include inline markdown.
  • image for the rich preview whenever someone shares a link to the page.
  • styles and scripts, which accept comma-separated lists of relative or absolute paths.
  • clean: false to skip name.html -> name/index.html rewriting.
  • index: false — Page will not be included in RSS feeds or the sitemap.

Templates

The /template folder contains a handful of HTML files that give pages their structure and styling.

Pages use the template frontmatter to specify which of these template HTML files to use. If omitted, default is used.

Templates can have frontmatter, too, though this is a more advanced topic that depends on the inner workings of the build system.


Macros

Pages & templates can contain macros, which look like: {{ rain-dogs }}.

Macros mark locations that the build system should do something.

The most basic macro is {{ content }}, which marks where pages will be injected into templates.

If there's no special behaviour defined for a macro, the default behaviour is to copy a value from the frontmatter. For instance, if the page frontmatter includes band: Zs and the template has {{band}} are so damn good!, the final page will have the text Zs are so damn good!. Accurate.

If you see a macro and you aren't sure what it does, take a look at /system/macros.ts — that's where all the macro expansion logic lives.


Includes

There's a folder of reusable snippets at /template/includes/. You can add HTML or MD files here, and then include them in your pages with the {{include:___}} macro.

For instance, the Automerge logo lives in /template/includes/logo.html, and can be included like so: {{ include: logo }}.



Other Features


Assets

Git is fine for version control of text. It's awful for images and videos — it remembers ever version of every asset that's ever been committed, and they slow down clones, diff, and other actions. Before adding images, videos, and other non-text assets to the repo, please do the following:

  1. Resize — if an image is only going to display at 1000px wide (at most), it should be no more than 2000px wide, and ideally closer to 1200px. (A tiny bit of extra detail is often enough to give the illusion of a crisp 2x retina image).
  2. Format — line art and screenshots should be PNG or WebP, photos should be WebP or JPG.
  3. Optimize — Use ImageOptim or Squoosh or whatever other tools you have available. Try to keep big photos down around 100-300kb, and screenshots around 10kb-100kb.

Fonts

In typical web development, you'd put a woff2 font file alongside your other assets, and then load it in your stylesheet. But fonts often contain a ton of wasted data — ligatures and alternates and glyphs for characters that are never used.

Instead, to add fonts to our website, you place ttf or otf files in the /fonts folder. The build system can then:

  1. Scan every page of the site, and collect every unique character of text.
  2. Create a subset of data in the ttf / otf files with just the characters we use.
  3. Create optimized woff2 files of those subset fonts, and save them to /content/static/fonts/.

The build system will redo step 1 every time it runs. It will only redo steps 2 & 3 if it notices that the set of unique characters has changed.

So, when you add, remove, or change any of the fonts in the /fonts folder, you need to force the build system to redo steps 2 & 3. To do that, just delete the /content/static/fonts/chars.txt file.

Caveats & Cautions

This automatic font subsetting requires two non-NPM binary dependencies: harfbuzz and woff2.

  • On Mac, you can brew install harfbuzz woff2
  • Not sure about Linux / Win — it is a goal to fully support these platforms, but that work hasn't been done yet.
  • It's fine if these deps are missing. The build system will still run, but when the set of characters changes it will log a single warning and skip regenerating the fonts.
  • Any characters that are missing will still be displayed on the site, they'll just appear in a fallback font.
  • TODO / Wishlist: These deps can be added to the Github Actions flow, ensuring we always have the correct font subsets when the site is deployed.

Redirects

In the Redirects.txt file, you'll find a list of redirect rules. One rule per line, space-separated.

/source         /destination
/old/busted     /new/hotness

Bare text is a comment 👋

The redirect source MUST start with a slash. The destination can be any URL.
/secret https://feelingisreality.com

You can redirect other kinds of files, too, not just HTML/Markdown pages.
We don't control the server, so we can't do a 301 or 302. Instead, the build system
will hardlink the file at the new path to the old path, so that both paths will work.
/old/path.pdf /new/path.pdf
  • Add a redirect whenever you move or rename an existing page or asset (ie: PDF) that someone might have bookmarked.
  • You can also use a redirect to create an alias so that multiple URLs will point to the same thing — but don't go overboard.
  • These redirects are excluded from the Sitemap.

Broken Links

The build system will automatically check internal links for validity. If you try to link to a page that doesn't exist, you'll see a warning in the terminal.

In the future, we'd like to add automatic checking for external links too, with some sort of assistance in adding a Wayback Machine fallback if links go dead. How best to do this is an open question — suggestions welcome!



System

The website includes the site CLI tool.

You can run site help to list all the available commands.

If site doesn't work, use ./site instead (or better yet, add . to your $PATH)

site is a little shell script at the root of the repo. It executes system/app.ts using the fastest available Node-compatible runtime (bun, deno, or node).

app.ts is the main entrypoint to the build system. If you want to learn how it works, start reading from there. It's all extensively commented, and a lot of care was taken to make it easy to understand and hack on.

About

The official website of the Automerge project, with docs, references, community links, and more!

Resources

License

Stars

Watchers

Forks