The website for Easy CMS: home page, docs, blog, changelog and showcase. It is a Next.js 16 app that runs Easy CMS itself.
| Part | Where the content lives |
|---|---|
| Home | app/page.tsx; the announcement badge and latest posts come from the CMS |
| Docs | Markdown from the Easy CMS repo, English at /docs and Thai at /th/docs, built into static pages |
| Blog, Changelog, Showcase | Easy CMS collections posts, releases, showcase, edited at /admin |
pnpm install
pnpm seed
pnpm devpnpm seed creates the SQLite database (cms.db) and fills empty collections with the starting
posts, releases and showcase entries. pnpm seed --reset replaces them. Open /admin to create the
first admin user.
The docs are written in the Easy CMS repo, next to the code: website/guide, website/reference,
website/th and website/sidebar.json (the navigation, shared with the VitePress site).
scripts/fetch-docs.mjs copies them into content/docs, and the admin screenshots into
public/screenshots. Neither is committed here.
| Docs come from | |
|---|---|
pnpm build (always fetches) |
the commit @easy-cms/core@latest was published from, read from its npm provenance |
DOCS_REF=main pnpm build |
a branch, tag or commit of maritonx/easy-cms |
DOCS_SOURCE=../EasyCMS |
a local checkout; put it in .env.local to write docs and see them here |
pnpm dev fetches only when content/docs is missing; pnpm docs:fetch fetches again.
Rendering:
lib/docs/sidebar.tsmaps each file insidebar.jsonto its URL in each language (guide/next→/docs/nextand/th/docs/next).components/docs/doc-page.tsxrenders both;lib/docs/i18n.tshas the page's own words.lib/docs/content.tsturns VitePress syntax into HTML:::: info|tip|warning|details,::: code-group,bash [pm]blocks (one tab per package manager),<Screenshot>, fence titles and highlighted lines, and{#id}heading anchors (the Thai pages keep the English anchors). Links between pages are rewritten to site URLs in the page's language.scripts/build-search.mtsbuilds the search indexes beforenext build:public/pagefind(English) andpublic/pagefind-th(Thai); the search dialog uses the one for the page's language.lib/docs/commands.tsis copied fromcreate-easy-cms, so the docs translate npm commands the same way the scaffolder does.
Schema changes ship as migrations: after changing easy-cms.config.ts, run
pnpm exec easy-cms migrate:create <name> and commit easy-cms/migrations. Production runs
easy-cms migrate before the new version starts. A database made by development push (your local
cms.db) can't take migrations; production databases start empty and are migrated.
Uses a Turso database, since Vercel has no persistent disk. vercel.json runs the migrations
before each build.
-
Create a Turso database:
turso db create easy-cms-io, thenturso db show --url easy-cms-ioandturso db tokens create easy-cms-io. -
Import
maritonx/easy-cms-websitein Vercel and add these environment variables:Variable Value EASY_CMS_SECRETopenssl rand -hex 32DATABASE_URLthe libsql://…URLDATABASE_AUTH_TOKENthe Turso token SITE_URLthe deployment's address DOCS_REFmain, until an Easy CMS release includeswebsite/sidebar.json -
Put
DATABASE_URLandDATABASE_AUTH_TOKENin.env.turso(not committed), then fill the database once from your machine withpnpm seed:turso.pnpm migrate:tursoruns pending migrations against it. Keep these out of.env:pnpm devreads.envand would push the development schema into the Turso database. Open/adminto create the first admin.
Limits of the trial: uploads are not kept between deploys (add @easy-cms/storage-s3 for that),
and Vercel Hobby crons run once a day, so scheduled publishing isn't on time.
One Node process with the SQLite file and uploads on the server's disk; no Turso or S3 needed. Scheduled publishing works because the server keeps running.
- Node 22.12 or later; build on the server (or the same OS and architecture), since SQLite uses a native driver.
.envwithEASY_CMS_SECRETandSITE_URL;DATABASE_URLdefaults tofile:./cms.db.- Deploy:
pnpm install --frozen-lockfile && pnpm exec easy-cms migrate && pnpm build, thenNODE_ENV=production pnpm startfrom the project root, under systemd or pm2, behind Caddy or nginx for HTTPS. - Back up
cms.dbanduploads/(see the Backups guide).
| Script | |
|---|---|
pnpm dev |
Development server |
pnpm build / pnpm start |
Production build and server |
pnpm docs:fetch |
Fetch the docs again |
pnpm seed |
Starting content for an empty database |
pnpm migrate:turso / pnpm seed:turso |
The same against the Turso database in .env.turso |
pnpm typecheck |
Route types and tsc |
pnpm lint |
ESLint |