01 — GETTING STARTED

From install to live in four steps

Selfish runs on iPhone, iPad, and Mac from a single purchase. The flow is always the same: write a post, generate the static site, point Selfish at your host once, and publish. You only do the connection setup a single time per site — then every publish is one tap.

01
Write
02
Generate
03
Connect
04
Publish
02 — CREATE A SITE

Add your first site

From the sites list, tap New Site. Each site keeps its own posts, pages, theme, and publishing target — so you can run as many as you like from one app. Everything below lives in Site Settings.

  1. 01Title — your site's name, shown on the generated site, e.g. Field Notes.
  2. 02Description & author (optional) — used on the site and in its RSS feed.
  3. 03Site URL — the final public address readers reach, e.g. https://fieldnotes.example. Used to build canonical links, sitemap.xml, and the RSS feed, so set it to wherever the site will actually live.
TIP

On a managed host you may not know the final URL until the site exists — set it to your *.netlify.app or *.pages.dev address (or your custom domain) once you have one, then re-publish so the feed and sitemap point to the right place.

03 — CHOOSE HOW TO PUBLISH

Pick a publishing route

Open Site Settings and set Publish Using. Selfish supports four targets — pick the one that matches where you want the site to live. You can switch any time, and each site remembers its own setup.

SFTP
Upload over SSH to a server you control — a VPS, a shared host, or a box at home. Most control; you manage the machine. Set up →
S3-compatible
Upload to object storage: Amazon S3, Cloudflare R2, Backblaze B2, DigitalOcean Spaces, or MinIO. Cheap and scalable; you enable public hosting or a CDN yourself. Set up →
Netlify
Deploy to a managed host with free HTTPS and a global CDN. No server to run — just a personal access token. Set up →
Cloudflare Pages
Deploy to Cloudflare's edge network with free HTTPS and CDN. No server to run — just an API token. Set up →
KEYCHAIN

Whichever route you choose, every secret — SFTP passwords and SSH keys, S3 secret keys, Netlify and Cloudflare tokens — is stored only in the Apple Keychain, never in a database, source, or log. Use Test Connection to check any setup before you publish.

04 — SET UP SFTP

Publish to your own server

Selfish publishes over SFTP — the file-transfer layer of SSH. If you can SSH into your box, you can publish to it. With Publish Using set to SFTP, fill in the server fields:

FIELD
WHAT TO ENTER
Host
Your server's address — a domain like ftp.example.com or an IP like 203.0.113.10.
User
Your SSH login, e.g. deploy or www-data.
Port
22 for almost everyone. Only change it if your host runs SSH on a custom port.
Remote Path
The absolute directory your web server serves from, e.g. /var/www/fieldnotes — often /public_html or /www on shared hosts. Selfish creates sub-folders as needed.
AUTH

Under Authentication, choose Password or SSH key. For a key, paste or import an OpenSSH RSA or Ed25519 private key (passphrases supported); other types like ECDSA aren't supported yet. Either way the secret lives only in the Keychain.

Finding your details

Where these live depends on your host. A few common setups:

VPS (DigitalOcean, Hetzner, Linode)
Host = the server IP, user = the account you SSH in as, path = wherever Nginx/Apache points (often /var/www/html).
Shared hosting / cPanel
Look for "SFTP / SSH access" in the panel. Path is usually ~/public_html.
Home server / NAS
Host = your local IP or domain, with SSH enabled. Make sure the port is reachable from your device.

Host-key trust (first connection)

The first time Selfish reaches a server it remembers that server's SSH host key and shows you its SHA256: fingerprint — trust-on-first-use, the same model as SSH itself. If the key ever changes, uploads are blocked, which is real protection against a server being impersonated.

Compare the fingerprint to what your host published (or to ssh-keyscan output) the first time you connect.

If the key later changes, Selfish stops the upload and warns you — investigate before continuing.

When you've legitimately rotated the key (a rebuilt server, say), use Reset Trusted Host Key in Site Settings and trust the new one.

05 — S3-COMPATIBLE STORAGE

Publish to S3, R2, B2 & more

Set Publish Using to S3 to upload to Amazon S3 or any S3-compatible service — Cloudflare R2, Backblaze B2, DigitalOcean Spaces, MinIO. Create a bucket and an access key in your provider's console first, then fill in:

FIELD
WHAT TO ENTER
Bucket
The bucket name, e.g. my-site-bucket.
Region
The bucket's region, e.g. us-east-1 — or auto for Cloudflare R2.
Endpoint
Leave empty for Amazon S3. For others, enter their endpoint host — <account-id>.r2.cloudflarestorage.com (R2), s3.us-west-004.backblazeb2.com (B2), and so on.
Path Prefix
(optional) Publish under a folder inside the bucket, e.g. blog.
Access Key ID
The access key from your provider, e.g. AKIA….
Secret Access Key
Stored in the Keychain only. Use a key scoped to write just this bucket.
SERVING

Object storage holds the files, but you choose how readers reach them: enable static website hosting on the bucket (Amazon S3) or connect a custom domain to the bucket (Cloudflare R2). Point your Site URL at that address.

06 — NETLIFY

Deploy to Netlify

Set Publish Using to Netlify to deploy straight to a Netlify site — free HTTPS and a global CDN, no server to run. Selfish deploys into a site that already exists, so create one first, then connect it:

  1. 01At app.netlify.com, create a site — drag-and-drop any folder once, or use Add new site.
  2. 02Copy its name.netlify.app domain, or its Site ID from Site configuration.
  3. 03Create a personal access token under User settings → Applications → Personal access tokens. Tokens now require an expiry date.
FIELD
WHAT TO ENTER
Site ID or Domain
The site's API ID, or any of its Netlify domains, e.g. mysite.netlify.app.
Personal Access Token
The token from above. Stored in the Keychain only.
FAST REPEATS

Netlify stores files by content hash, so unchanged files never re-upload — repeat publishes of a photo-heavy site are quick. Netlify allows 3 deploys per minute; if a publish is rate-limited, wait a moment and try again.

07 — CLOUDFLARE PAGES

Deploy to Cloudflare Pages

Set Publish Using to Cloudflare Pages to deploy to Cloudflare's edge network — free HTTPS and CDN, no server to run. As with Netlify, the project must exist first:

  1. 01At dash.cloudflare.com → Workers & Pages, create a Pages project using Direct Upload.
  2. 02Copy your Account ID from the Workers & Pages overview, and the project's name.
  3. 03Create an API token at My Profile → API Tokens → Create Token with the Account → Cloudflare Pages → Edit permission.
FIELD
WHAT TO ENTER
Account ID
Your 32-character hex account ID.
Project Name
The Pages project's name (not an ID), e.g. my-site.
API Token
The token from above, with Cloudflare Pages: Edit. Stored in the Keychain only.
NOTE

Each publish creates a new production deployment on your *.pages.dev domain. Cloudflare Pages allows up to 20,000 files per deployment and 25 MiB per file. Unchanged files are skipped on repeat publishes.

08 — TEST & PUBLISH

Check the connection, then go live

Before you ever publish, tap Test Connection. Selfish verifies your credentials and target — for SFTP it also checks the remote path, creating it if needed — so you find problems now, not mid-upload. Then tap Publish: Selfish renders every published post and page to static HTML, with your sitemap.xml and RSS feed, and uploads the whole site with per-file progress.

generating static site…
142 pages rendered · sitemap.xml · feed.xml
uploading ████████████ 100%
live at https://fieldnotes.example

Drafts stay private — only posts marked Published are generated and uploaded. On S3, Netlify, and Cloudflare Pages, files that haven't changed are skipped, so repeat publishes are fast.

09 — THEMES

Four built-in themes

Every theme is responsive, fast, and dependency-free. Switch any time and re-publish — your content never changes, only the wrapper. You can also inject custom header / footer snippets for analytics-free extras like a web font or a verification tag.

Default
Clean & minimal, system fonts
Modern
Bold type, vibrant accents
Classic
Traditional serif, timeless
Sky
Social feed with image mosaics

Three more — Mono, Editorial, and Zine — are available in the Theme Gallery as optional one-time purchases. Publishing is never paywalled. See all themes →

10 — TROUBLESHOOTING

Common issues

SFTP · connection refused / timeout
The host or port is wrong, or a firewall is blocking it. Confirm you can ssh user@host -p 22 from a computer first.
SFTP · authentication failed
Username, password, or key is off. For keys, make sure it's an OpenSSH RSA or Ed25519 key. Secrets are read fresh from the Keychain on each publish.
SFTP · permission denied on upload
Your user can log in but can't write to the remote path. Check directory ownership, or point at a path your user owns.
SFTP · host key has changed
Expected after a legitimate server rebuild or key rotation — use Reset Trusted Host Key. If you weren't expecting it, stop and investigate.
S3 · access denied
The access key can't write to the bucket, or the region/endpoint is wrong. Use a key with write permission on this bucket, and set auto as the region for R2.
S3 · site uploads but won't load
The files are there but not served publicly. Enable static website hosting (S3) or connect a custom domain (R2).
Netlify · token invalid or expired
Create a fresh personal access token — tokens now require an expiry date, and resetting your Netlify password invalidates existing ones.
Netlify · rate limited
Netlify allows 3 deploys per minute. Wait a minute and publish again.
Cloudflare · token invalid
The API token is missing the Account → Cloudflare Pages → Edit permission, or the account ID / project name is wrong. Check the project exists under Workers & Pages.
READY?
Get Selfish and publish your first site