Concepts
How publishing works
A peek behind the curtain — what happens between div deploy and your website going live.
How publishing works
div deploy is short, but a few interesting things happen between you typing it and your website appearing on the internet. This page walks through the whole pipeline so that if anything ever doesn't go to plan, you can debug from a position of understanding.
#The pipeline
your folder ──► CLI ──► API ──► S3 ──► CloudFront ──► <slug>.div.so
Each arrow is doing real work. Let's follow the bytes.
#1. The CLI walks your folder
div deploy reads every file in the current directory recursively, applies the built-in ignores and your .divignore, and builds an in-memory list of { path, content } pairs. Files larger than 10 MB are dropped with a warning. Files whose extension isn't on the allowlist are dropped with a warning. The whole deploy is capped at 50 MB; if you're over, the CLI bails before uploading anything so you never end up with a half-finished website.
#2. The CLI calls the API
For a first deploy, the CLI hits POST /api/cli/deploy/init with your email and folder name. The server:
- Generates a unique slug from your folder name (e.g.
mysite-a4f9d2). - Creates an unverified user account tied to your email (if one doesn't already exist).
- Creates a locked project for that user with the new slug.
- Returns the slug, a 48-character claim token, and the eventual public URL.
For a re-deploy, this step is skipped — the CLI uses the saved slug + claim token and goes straight to uploading.
#3. The CLI uploads each file
Each file is sent base64-encoded to PUT /api/cli/deploy/<slug>/files, with the claim token in the Authorization header. The CLI uploads up to 8 files at a time. The server validates the path (no .., no absolute paths), checks the size, and writes the file to storage.
#4. The server writes to storage
Every write goes through a single function (ProjectStorage::writeFile). That function:
- Decides whether the project is in plain mode or SSG mode and writes accordingly.
- Sets
Cache-Control: no-cache, max-age=0so CloudFront re-validates against S3 on every request. - Sets the file's visibility to public so the CDN can serve it.
- Bumps the project's
updated_atso the editor's preview iframe knows to refresh.
The filesystem is S3 in production. Locally, it's the Laravel app's storage/app/projects/<slug>/ directory.
#5. The CLI asks the server to send a verification email
For first deploys only, the CLI hits POST /api/cli/deploy/<slug>/claim. The server emails you a one-time signed URL with a 24-hour TTL.
#6. You click the link
The signed URL goes to /claim/verify. The server:
- Marks your email verified.
- Clears the project's locked state and claim token.
- Flips the project to public.
- Redirects you to
<slug>.div.so.
That's the moment your website becomes visible to anyone else. 🎉
#How serving works
In production, <slug>.div.so is a wildcard CloudFront distribution backed by an S3 bucket. CloudFront's edge cache holds responses, but Cache-Control: no-cache, max-age=0 (set on every write) forces revalidation against S3 — so when you re-deploy, visitors see the new files within a request or two. No mysterious TTL waiting games.
Locally, when you point the CLI at a development copy of Div, there's no CloudFront and no S3. The Laravel app registers a {slug}.div.test domain route that reads files straight out of storage/app/projects/<slug>/ and serves them with the same Cache-Control header. Your *.div.test DNS resolution comes from Herd, Valet, or dnsmasq.
#What lives where
storage/app/projects/<slug>/...(local) ors3://div.so/<slug>/...(prod) — the actual files behind your website.projectstable — the row that ties the slug to your user account, holdsis_public,locked_at,claim_token, etc.userstable — the account tied to your email.~/.config/div/auth.json(local CLI) — your saved claim tokens.~/.config/div/config.json(local CLI) —api-urlandinsecure../div.json(local CLI) — the project's slug, committed to git so collaborators see it.
#See also
div deploy— the user-facing command.- Authentication — claim tokens, signed URLs, and
div login. - Template variables — what happens in SSG mode.