Contents

On Vercel

Vercel runs the kit without a server of its own: each request starts a function, and nothing lives between them. Three things are therefore elsewhere than on a server: uploaded files go to Vercel Blob, the database is a hosted one, and Vercel Cron runs the background jobs. The kit is set up for all three; vercel.json in the repository holds the cron and the functions' time limit.

What it takes #

A Vercel planPro. Hobby is for non-commercial use only, runs a cron once a day, and gives functions at most 60 seconds. To try the kit on Hobby anyway, see On Hobby.
A databasePostgreSQL (Neon, from the Vercel Marketplace) or MongoDB (Atlas). See The database.
A Blob storeCreated under the project's Storage tab. Connecting it sets BLOB_READ_WRITE_TOKEN.

Set it up #

  1. Import your copy of the repository into a new Vercel project. The framework is detected as Next.js; keep the defaults.
  2. Add the database.
    • Postgres (Neon): add it from the Storage tab and use its pooled connection string as DATABASE_URL. Set the project's Build Command to pnpm payload migrate && pnpm build, so the migrations run once per deploy, before any function starts (see The database).
    • MongoDB (Atlas): use the cluster's mongodb+srv:// string as DATABASE_URL. Atlas must accept connections from Vercel's functions, whose addresses change: allow 0.0.0.0/0, or use Atlas's Vercel integration.
  3. Add a Blob store under Storage and connect it to the project. That sets BLOB_READ_WRITE_TOKEN, and with it every upload goes to Blob.
  4. Set the environment under Settings → Environment Variables:
    • PAYLOAD_SECRET: openssl rand -hex 32
    • CRON_SECRET: openssl rand -hex 32. Vercel Cron sends it to the run endpoint by itself.
    • NEXT_PUBLIC_SERVER_URL: the site's address. Without it, the kit uses the production domain Vercel knows, and a preview its own address.
    • the optional services you use: ANTHROPIC_API_KEY, SMTP and so on (Environment variables).
  5. Deploy, open /admin and create the first admin.

How it differs from a server #

  • Uploads are on Blob.
    • The media library's files are public and served by Blob's CDN, video included.
    • Files to translate and their translations stay behind Payload's access rules.
    • Each file name gets a random part, so nobody can guess an address.
    • The admin uploads straight from the browser to Blob, so a large picture or video never passes through a function.
    • A site that already has files on disk does not move them by itself: upload them again, or copy them to the store with their names.
  • The background jobs run from Vercel Cron.
    • vercel.json calls /api/payload-jobs/run?allQueues=true every minute.
    • The kit turns off its own timer on Vercel (JOBS_AUTORUN is not needed).
    • A job made of steps, such as translating a file into several languages or proofreading the site, moves one step a minute.
    • See Background jobs.
  • Functions have a time limit.
    • vercel.json gives the API's function 300 seconds, which covers ✨ Translate on a long page, Distill and an evaluation.
    • Longer work already runs as jobs, one step per call.
  • A request carries at most 4.5 MB. Admin uploads go straight to Blob, so they are not affected. These pass through a function, and their files must fit:
    • Translate a file (the upload, and the download of the translation)
    • replacing a media file's file
    • importing translations
  • The page cache is shared by every function, so a publish refreshes the site at once, everywhere.

On Hobby #

Change vercel.json before the first deploy, or the deploy is refused:

  • the cron's schedule to once a day, e.g. 0 3 * * *
  • maxDuration to 60

Scheduled publishing and file translations then wait for the next day, and ✨ Translate on a long page may run out of time. It is enough to look around, not to run a site. Hobby may not be used commercially.

A live demo on Vercel #

A live demo runs on Vercel as on a server, with one addition: set DEMO_MODE=true for the build as well as at runtime.

  • The nightly reset writes the demo's photographs, films and recorded translations again. Their paths are read at runtime, so the build cannot follow them.
  • With DEMO_MODE=true at build time, next.config.ts puts them (about 17 MB) into the API's function.
  • The reset then runs from Vercel Cron at DEMO_RESET_AT, and writes its pictures to Blob.

In demo mode a visitor may upload files of at most 4 MB on Vercel, not 5 MB, so Translate a file stays under the request limit.

These guides ship with Tolk Starter 0.6.0: buyers get the same pages in their repository, next to the code they describe.