ZeroPress Studio Documentation

Content

Content Search

Studio searches Posts and Pages using derived, contentful FTS5 tables in Studio D1. The saved documents remain authoritative. This index serves Studio content lists; the public site’s static search is built separately.

Indexed Text

Each Post and Page contributes its title, slug, excerpt, and reader-visible body text. Autosaves and saved revisions are not separate results. Draft, Published, and Trash documents are indexed, then filtered by the selected status and the account’s permitted content scope. All excludes Trash.

Format Body projection
HTML Decoded text nodes; tags, attributes, comments, and script/style/template contents removed
Markdown Rendered labels and text; markup, link destinations, and hidden HTML contents removed
Plain text Control characters removed and whitespace collapsed

The full projected body is indexed. The FTS row uses the document’s public ID and stores its source revision for consistency checks.

Query and Ranking

The query is trimmed and limited to 200 UTF-16 code units. Unicode letters and digits form tokens; internal ., _, and -, and names such as C++ and C#, are retained. Duplicate tokens are removed without regard to case.

Every token is required, but tokens may match different fields. Studio does not interpret user input as raw FTS operators, wildcards, or column selectors.

The index uses the FTS5 trigram tokenizer with case-insensitive and diacritic handling. Tokens of at least three code points use quoted FTS MATCH queries. One- and two-code-point tokens use bound substring checks against the derived text; a query containing only short tokens scans that derived table.

Long-token matches use BM25 weights of 8 for title, 5 for slug, 3 for excerpt, and 1 for body. Short-token-only queries use the corresponding field priority. Ties use most recently updated, then document ID. Lists without a search query keep their normal ordering.

Excerpt and body matches can include a bounded plain-text context. The browser adds highlighting from returned ranges; the API does not return snippet HTML. Queries and snippets are excluded from operational logs.

Keeping the Index Consistent

Content writes and the corresponding FTS updates share the same D1 batch. This includes changed imports and restored revisions. A failed batch leaves neither side changed; unchanged saves and imports do not rewrite the index. Delete triggers remove derived rows when documents are permanently deleted.

An index rebuild uses checkpoints and revision checks so a batch cannot overwrite a newer edit. Completion verifies counts, source revisions, orphan rows, and FTS integrity before search becomes ready.

Rebuilding

Fresh installations start with an empty, ready index. A logical restore or an upgrade that invalidates search data marks it rebuild_required.

State Action
rebuild_required in operational mode An administrator can start Rebuild from Dashboard → Service readiness → Post and Page search
Interrupted Dashboard rebuild Select Continue rebuild; keep the Dashboard open to advance it
recovery_required or a forced restart Use Operations in maintenance or recovery mode, with administrator re-verification

The Dashboard path needs no Operations token or IP setup. Lists, editing, and imports remain available while the index is rebuilt. Both rebuild paths share the same saved checkpoint and cannot run conflicting database operations.

Search against a non-ready index returns CONTENT_SEARCH_INDEX_NOT_READY; an index service failure returns CONTENT_SEARCH_INDEX_UNAVAILABLE. These errors are not empty search results. An input with no searchable tokens returns CONTENT_SEARCH_QUERY_INVALID.

Backup and Restore

Studio logical backups preserve canonical content and the managed FTS schema, but omit FTS shadow tables and derived rows. Restore creates an index that needs rebuilding. Use Studio backup and restore for this schema rather than native D1 export of its virtual tables.

SQLite documents the underlying FTS5 trigram tokenizer.