Fairpage

fairpage-cli

Reference

The commands and the rules a site follows. The full reference for building is fairpage docs, served by the app and current with it.

Install

fairpage-cli is one binary, fairpage, for macOS and Linux on Intel and ARM, and for Windows on Intel. There is nothing else to install: no Node, no build step.

# macOS and Linux
curl -fsSL https://fairpage.co/install.sh | sh

# Windows, in PowerShell
powershell -c "irm https://fairpage.co/install.ps1 | iex"
  • The script checks the download against its published checksum and puts fairpage in /usr/local/bin when it can write there, else ~/.local/bin; on Windows, in %LOCALAPPDATA%\Programs\fairpage. FAIRPAGE_PREFIX picks another folder.
  • fairpage update installs a newer release once its signature checks out, and fairpage dev says once a day when there is one. FAIRPAGE_VERSION=v0.1.0 with the script installs a given version.

Log in

You log in once per computer, to your Fairpage account. login shows a code and opens the approval page in your browser. Log in there if you have to, check that the code matches your terminal and choose Approve.

fairpage login
# Open https://fairpage.co/cli/approve and check the code: BCDF-GHJK
  • The login reaches every site you are a member of. fairpage sites lists them; clone without a name offers them, and takes the only one when you have one. fairpage new "Nord Bakery" starts a site you own, as “New site” on your sites page does.
  • Codes last ten minutes. --url logs in to another Fairpage, such as --url=localhost:3000 for one on your machine.
  • Tokens are stored in ~/.config/fairpage/credentials.json, readable only by you. FAIRPAGE_TOKEN overrides it, for CI.
  • fairpage logout forgets the token on this machine. To cut it off everywhere, revoke it on your account page.

Day to day

You and the owner edit one shared draft. The live site changes only when someone publishes.

  1. Pull before you start. fairpage pull brings in what the owner changed in the editor.
  2. Work locally. fairpage dev serves the site on localhost:4321, rendered by Fairpage with your unpushed files laid over the draft. The page reloads when you save, and styleguide problems show as warnings.
  3. Push when a piece of work is done. A push is all or nothing, and it becomes one step in the site’s history, so the owner can undo it like their own changes.
  4. Publish when it’s ready. fairpage publish lists what differs from the live site and asks before it goes. --restore puts the previous version back.

Commands

Every command takes --json for scripts.

Account and sites

login
Log in to your account through the browser. --token stores a token you already have; --no-browser only prints the address.
logout
Forget this machine’s token for the app. The token works until you revoke it on your account page.
whoami
The account you are logged in as.
sites
Your sites, the ones you own marked, with the editor’s address.
new <name>
Start a site you own. --slug chooses its address.
invite <email>
Mail an invitation to this folder’s site; --owner hands the site over. The link works for 7 days.

Syncing

clone [site] [folder]
Download a site’s draft into a new folder, named after the site by default. Without a site, your only one, or one you pick from a list.
status
Local changes, draft changes, files changed on both sides, and conflicts waiting to be resolved.
pull
Take the draft’s changes. A file changed on both sides is kept aside in .fairpage/theirs/ and the command exits with 2.
resolve [path…]
Settle conflicts, keeping your file. --theirs keeps the draft’s version instead.

Building and shipping

dev
Preview on localhost with live reload. --port picks the port (4321 by default); --open opens the browser.
check
Check your changes as a push would and render every page, without writing anything. Exits with 1 on any problem.
push
Send local changes to the draft, all or nothing. --dry-run shows what would go.
publish
Show draft against live, ask, publish. -y skips the question; --restore swaps the previous publish back.
rows push <collection> <file>
Import rows into a collection from JSON or CSV, up to 5,000 at a time. Rows without a status are published.

Moving a site in

import <url>
Copy an old site into .legacy/: every page as served, the files they use and import.json. Nothing is sent to Fairpage, and .legacy/ is never pushed.
compare [path…]
Render each address of the imported site with your changes and list what differs from the old page. Exits with 1 when anything differs.

The CLI

docs [words…]
The reference for building sites, from the app. --search finds paragraphs, --list names the sections. Needs no login.
update
Install the newest release once its signature checks out.

A site’s files

A site is plain files. Paths that start with _, and components/, never answer a URL.

index.x.html
The home page, at /. about.x.html is /about; services/index.x.html is /services.
_layout.x.html
Wraps every page in its folder and renders <slot />.
components/card.x.html
Used as <card />; attributes become props.
_content/schema.yaml
The collections and their fields. A page reads one as content.posts.
blog/[posts].x.html
One page per row of the collection in the brackets, at /blog/<slug>, which it reads as item. The folder is any path, so addresses need not follow the collection’s name.
_styleguide/
theme.css with the tokens, guide.md with the rules in words, and example sections/.
_pages.yaml
Descriptions, share images and redirects.
public/
Served as is: favicon.svg, fonts, files.
404.x.html
The not-found page.

Markup and styles

Pages are HTML with expressions in braces and control flow as attributes. There is no <script> in a site’s pages.

<title>Journal</title>
<h1 class="text-4xl font-display text-ink">Journal</h1>

<article @each={content.posts as post} class="py-8 border-b border-line">
  <a href={"/posts/" + post.slug}>{post.title}</a>
  <p @if={post.summary}>{post.summary}</p>
</article>

Classes are Tailwind 4 utilities over the site’s own tokens, compiled by Fairpage. There is no default palette and no arbitrary values: p-[13px] and inline style properties are refused, which keeps the owner’s edits and the AI’s on brand. dev shows a refused class as a warning; push and publish stop on it.

Agents

clone writes an AGENTS.md into the folder, unless one is there already. It covers the commands, the working order, the file layout and moving a site in, so an agent can build and push without a briefing. For the rest, fairpage docs markup, docs utilities or docs --search <term> prints the reference from the server, current with it. Neither AGENTS.md nor CLAUDE.md is synced to the site.

cd acme
claude "Add a Journal: a posts collection, a list page and a page per post, in the styleguide's type scale."

Drafts, conflicts, limits

Conflicts

If the draft changed under you, a push is refused with the files in question: pull, resolve, push again. Nothing pushes while conflicts are waiting.

What the plan decides

On Plus and above, anyone on the site changes the collection schema, the styleguide and, on a styleguide site, any CSS. On Lite, people change content, pages and sections within them. A schema change can add fields; to retire one mark it removed: true, to rename use was:. The content is migrated on push.

Publishing

Publish is refused while any page in the draft has errors, or when there is no index.x.html. Local changes you haven’t pushed are not published. A custom domain is connected on the site’s Domains page.

Limits

10 MBper file
100 MBper push
500 MBand 5,000 files per site
255characters per path, 16 folders deep
600requests a minute per token
5,000rows per import