How Tovu works
Tovu is local-first: each site is one folder on disk — its database, media, and theme together — served by a single process on your machine and rendered through a theme you choose.
The site folder
- content.db — a SQLite database holding your posts, pages, menus, media metadata, forms, and settings.
- chat.db — the assistant's chat history, kept separate from your content.
- uploads/ — the media files themselves.
- themes/ — your theme, copied into the site and editable in place.
- plugins/, overrides/, skills/, agent-plugins/ — installed plugins, your own overrides, and assistant skills and plugins.
- ops/ and out/ — operational journals, and publish or export output.
- config.json — site configuration.
A new site starts with all of this already in place.
Three processes
- The server — one process serves both the public site and the admin at
/admin. It's whattovu servestarts. - The agent daemon — a separate process that runs the assistant's tools. It starts only after the server has finished booting, opens its own connection to the same
content.db(safe, because SQLite runs in WAL mode), and doesn't start at all if the assistant is turned off. - The desktop app — runs
tovu servefor you, one server per open site window.
How a request becomes a page
- The home page (
/) renders a Page saved at slug/, if you have one, or the theme's own home template if you don't. - Any other address checks the theme's own marketing pages first; a published post or page at the same address normally wins over one.
- Posts render through their chosen template; Pages use the template you picked, or the theme's default page shell.
- The template renders, embeds resolve (see Embeds), the theme adds its partials and menus, and the page gets its SEO tags and the visitor-chat widget.
Rendering a public page:
Where content lives
All of it is tables in content.db:
- posts — Posts and Pages together, told apart by a
kindcolumn, with apost_revisionshistory table. - entries and content_types — your collections, and internally, widgets and widget areas, with an
entry_revisionshistory table. - media — file metadata; the files themselves live in
uploads/. - menus — your navigation menus.
- form_definitions and form_submissions — your forms and what visitors send you.
- taxonomies, terms, and entry_terms — categories and tags, and what they're assigned to.
- setting_* — site and admin settings.
Posts
A Post is rich-text content — a title, a body, and a status of draft or published. See Posts for the editor.
How posts work
You write in a normal rich-text editor — headings, lists, links, images, code blocks. A Post can't hold custom HTML; that's what a Page is for.
Pages
A Page works like a Post, but can also hold HTML you write yourself for full control over layout.
How pages work
Switching a Page to custom HTML is one-way — once you save HTML, the rich-text version is gone. This page you're reading is an HTML Page.
Menus
A Menu is a navigation tree you build in the admin — the header above and the sidebar beside this text are both ordinary menus.
How menus work
Each item can point at a URL, a route, an entry (a page or post), or a category or tag, and nested items become dropdowns. See Menus for the full editor walkthrough.
Media
Media is any uploaded image or video — with alt text, captions, and credit — that you can drop into a Post or Page. See Media for uploading and details.
How media works
Inside a Post it's a normal image node. Inside an HTML Page, you place one with a marker that's resolved when the page renders — see Embeds.
Widgets
A Widget is a reusable block — text, social links, recent entries, a menu, or a contact form — that you build once and place wherever you need it.
How embeds work
On an HTML Page, widgets, media, and other content all embed the same way, through a marker like this:
<div data-embed-config='{"type":"widget","slug":"contact-form"}'></div>
See Embeds for every marker type, its keys, and what happens when something doesn't resolve.
Themes
A theme is a folder of files, installed into your site, that decides how everything above looks. Themes come in tiers, from pure data to fully editable code.
Tiers, at a glance
- Declarative — a manifest and design tokens. No code runs.
- Templated — the same data plus real logic, in LiquidJS.
- Handlebars — the same idea, in Handlebars templates.
- Static — plain HTML, CSS, and JS, one file per route, every byte editable. This site's theme is static-tier.
- Code — its own tier in theme.json, but renders through the same engine as Declarative today.
See How Themes Work for the manifest, template, and authoring details, and How Plugins Work for how plugins extend a theme.
The assistant
An assistant lives in the admin, backed by the agent daemon described above. It has tools to read and change your content, media, menus, and more — see the tool catalog for the full list.
Let the admin do the work
- Ask the assistant — click the sparkle button in the bottom-right corner of the admin and say what you want, like "add a Contact page" or "publish my draft". The assistant does it for you: it calls tools — small, named actions such as "create a page" or "upload media" — and each one shows in the chat as it runs. See The assistant.
- Drag and drop — in the post editor, drop or paste an image or video to upload and insert it, and drag a block by its grip to move it. Drop a folder onto the assistant's chat to point it at that folder.
Publishing
Tovu is local until you publish it somewhere.
- Static export — export your site and publish it to GitHub Pages, Vercel, Netlify, Cloudflare Pages, or an S3-compatible bucket.
- Publish Content — push posts and pages straight to another Tovu site, with a plan step and conflict detection first.
- GitHub deployment — deploy from a repository through a connected GitHub App.