# CMS

Add an inline-editing CMS to the project, served from the app's own server or from a hosted one. It works in any SvelteKit project, including one Vela did not create.

### Syntax

```
$ vela enable cms
$ vela enable cms --endpoint https://velastack.dev/v1/projects/<project>/cms
```

This installs [`@velastack/cms`](https://www.npmjs.com/package/@velastack/cms) and `marked`, then wires the CMS into the app:

- A `loadCms` call in the root `+layout.server.ts`, created if the project has none, so every page receives its content and a deleted page answers 404, 410 or a redirect
- An `<AdminBar />` in the root `+layout.svelte`, where editors sign in to edit copy in place, upload media and publish
- The Vite plugin, which finds every editable field at build time

### Where the CMS lives

The command decides where the CMS backend runs, in this order:

1. `--endpoint <url>` always wins: the app reads from the hosted CMS at that URL.
2. An app that runs as a Node server hosts the CMS itself. That is a project with a [PocketBase backend](/enable/backend), or one on `@sveltejs/adapter-node` with no PocketBase at all, which is where [`vela deploy`](/deploy) leaves a project from `npx sv create`. `@sveltejs/adapter-auto` does not count: it decides per platform, and most of what it picks has no disk to keep a database on.
3. Otherwise, a project [linked](/link) to velastack.dev uses that project's hosted CMS, so `vela link` followed by `vela enable cms` needs no URL. The command says which endpoint it picked.
4. Otherwise it stops without changing anything and lists the ways forward: link the project, pass `--endpoint`, or give the app a server with [`vela enable backend`](/enable/backend) or `@sveltejs/adapter-node`.

An app that hosts the CMS also gets `better-sqlite3` and [`@velastack/kit`](/helpers/kit) installed, and the backend mounted at `/api/cms`, with its SQLite database and uploads in the data directory. The CMS keeps its own database; PocketBase is never involved.

With a hosted CMS, from `--endpoint` or from the link, the app reads from a CMS that runs elsewhere and the admin bar signs in there. That is the only shape a static site can use, since it has no server to host the backend; `vela build` then prerenders the published content and downloads its media into the site. A site velastack.dev hosts is rebuilt that way by [`vela cms deploy`](/cms/deploy) or by **Deploy Site…** in the admin bar.

Every project on velastack.dev has a hosted CMS at `https://velastack.dev/v1/projects/<project>/cms`, where `<project>` is the id [`vela link`](/link) records. The CMS-ready templates from [`vela create`](/create) arrive with this wiring in place and the endpoint of the linked project already in `src/lib/site.ts`, so they need no `vela enable cms`.

With [i18n](/enable/i18n) enabled, either shape uses the site's locales instead of a single default.

### Editors

An app that hosts the backend signs editors in against the CMS's own table, which starts empty. Create the first login, then open any page with `?edit` on the URL and sign in:

```
$ vela cms editor add you@example.com
```

The password is generated and shown once. `vela cms editor password <email> <password>` sets a new one, and `vela cms editor list` shows who can sign in; see [`vela cms editor`](/cms/editor). A hosted CMS manages its own editors.

### Making content editable

Wrap copy in the components from `@velastack/cms`. Each takes a `name` for the field and a `fallback` for when nothing has been published yet:

```svelte
<script lang="ts">
	import { CmsText, CmsImage } from '@velastack/cms';
</script>

<h1><CmsText name="hero.title" fallback="Welcome" /></h1>
<CmsImage name="hero.image" alt="Hero" />
```

### Re-running

Running the command again only fills in what is missing. `src/lib/cms.ts` and, for a backend the app hosts, `src/lib/server/cms.ts` and the two routes are yours once written and are never overwritten, so edits such as adding locales survive.

### Reverting

There is no `vela disable cms` yet. Delete `src/lib/cms.ts` and, if the app hosts the backend, `src/lib/server/cms.ts`, `src/routes/api/cms` and `src/routes/uploads`; remove `cms()` from `vite.config.ts`, the `loadCms` call from `+layout.server.ts` and `<AdminBar />` from `+layout.svelte`; then uninstall `@velastack/cms`, `marked` and `better-sqlite3`. `@velastack/kit` stays if the project has a PocketBase backend, which uses it too.