Guides

Working with a local backend

Pointing the CLI at a development copy of Div for end-to-end testing.

Working with a local backend

If you're contributing to Div itself — or you're self-hosting — you'll want the CLI to talk to a local copy of the Laravel app instead of the production API at https://div.so. This guide walks through that setup end to end.

If you're just trying to ship a website, you don't need any of this — div deploy already targets production by default. Skip ahead!

#Prerequisites

  • A working local checkout of the Div Laravel app.
  • A local DNS resolver that handles *.test (Herd, Valet, or dnsmasq).
  • The Div CLI installed.

#Point the CLI at your local app

Once. Per machine:

div config set api-url https://div.test
div config set insecure true

What these do:

  • api-url — overrides the default https://div.so for every CLI command.
  • insecure — sets NODE_TLS_REJECT_UNAUTHORIZED=0 at startup, so Node's fetch accepts Herd's self-signed certificate. Only set this for local development hosts. It disables certificate verification for the entire process.

Confirm:

div config get
# api-url = https://div.test
# insecure = true

To go back to production:

div config unset api-url
div config unset insecure

#Make sure the Laravel app uses local storage

The CLI writes files through the Laravel app, so the destination depends on the Laravel app's FILESYSTEM_DISK. For local end-to-end testing, you want files to land on disk, not in S3.

In your local .env:

PROJECTS_DISK=projects
PROJECTS_PREVIEW_HOST=div.test
MAIL_MAILER=log

What these do:

  • PROJECTS_DISK=projects — points project file storage at the local projects disk (which writes to storage/app/projects/<slug>/ by default).
  • PROJECTS_PREVIEW_HOST=div.test — tells the app to register a {slug}.div.test route that serves files from local storage. The route is only registered when PROJECTS_DISK resolves to a local driver, so production isn't affected.
  • MAIL_MAILER=log — writes verification emails to storage/logs/laravel.log instead of trying to send them. You'll grab the verify URL from the log.

Restart php artisan serve (or composer run dev) after editing .env.

#Run a deploy

In a website folder:

div deploy

Enter an email when prompted. The CLI will:

  1. Hit https://div.test/api/cli/deploy/init.
  2. Upload each file to storage/app/projects/<slug>/....
  3. Ask the server to send a verification email.

The "email" is now a log entry. Find it:

tail -n 50 /path/to/div/storage/logs/laravel.log | grep claim

Look for the signed URL (it'll look like https://div.test/claim/verify/<id>?expires=...&signature=...). Open it in a browser. You'll be redirected to <slug>.div.test, served straight from storage/app/projects/<slug>/.

#Verify the loop works

After the deploy, edit a file in your project and re-run div deploy:

div deploy
# ✓ Updated <slug>.div.test

Refresh <slug>.div.test in your browser. You should see the change. If you do — congrats, your local loop works end-to-end.

#Troubleshooting

#Couldn't reach https://div.test: fetch failed

Most likely the Laravel app isn't running, or div.test doesn't resolve. Check:

curl -v https://div.test/api/cli/deploy/init

If curl fails too, the issue is DNS or your Laravel app, not the CLI.

#SQLSTATE[HY000]: General error: 1 no such column: claim_source

Your local database is out of date. From the Laravel app's root:

php artisan migrate

#TLS warning every deploy

Warning: Setting the NODE_TLS_REJECT_UNAUTHORIZED environment variable to '0'
makes TLS connections and HTTPS requests insecure...

This is Node telling you that insecure: true is doing exactly what you asked. Expected. You can suppress it with --no-warnings if you really want, but it's a useful reminder if the env ever leaked outside your dev box.

#The verification link doesn't open my local site

If clicking the link redirects somewhere unexpected, double-check:

  • PROJECTS_PREVIEW_HOST=div.test is set in .env.
  • Your DNS resolver returns a local address for <slug>.div.test.
  • The website itself isn't locked (the CLI flow auto-clears locked_at on verify, but a stuck row can stay locked — check the projects table).

#Going back to production

div config unset api-url
div config unset insecure

Now div deploy targets https://div.so again. The ~/.config/div/auth.json file is shared across the production and local runs, but tokens are scoped by slug — there's no risk of a local claim token being submitted to prod.

#See also