Logo VitNode

Introduction

Declare a content type once in TypeScript and the VitNode Content Engine generates its Postgres table, validation, staff API, permissions and AdminCP screens.

The Content Engine turns one TypeScript definition into structured content for your plugin. You describe the fields of an article or a category, and VitNode generates the database table, Zod validation, staff-only API routes, staff permissions and AdminCP screens. Optional blocks add drafts, a public API, pages with SEO metadata, revisions, scheduling, live editing, translations and search.

This is the whole definition behind the example plugin's Categories screen:

plugins/example/src/content/category.ts
import { defineContentType, field } from "@vitnode/core/content";

export const categoryContentType = defineContentType({
  id: "example.category",
  tableName: "example_categories",
  fields: {
    name: field.text({ required: true, minLength: 1, maxLength: 100 }),
  },
  admin: {
    path: "example/categories",
    list: {
      columns: ["name", "createdAt"],
      orderableFields: ["name"],
    },
  },
});

Its sibling example.article turns on more blocks. Same engine, more fields, a busier list:

AdminCP Articles list from the example plugin, generated by the Content Engine, with published and draft articles in Status, Title, Slug, Reference code, Category, Author, Published at and Updated columns

What you get

From the definitionVitNode generates
fieldsA Postgres table with system columns and indexes, Zod schemas and a typed service
adminAn AdminCP list with search, sorting and bulk actions, plus create and edit forms
Every content typeStaff routes and the can_view, can_create, can_edit and can_delete permissions
publicationDraft and published states, a can_publish permission and Publish buttons
publicApiRead-only public routes that return only the fields you list
deliveryPage URLs, SEO metadata, slug redirects and sitemap entries
editorialRevisions with restore, preview links and scheduling
liveEditingField locks, an autosaved shared draft and presence in the AdminCP edit form
localizationA translations table and per-language fields and publishing
searchRecords in the site search index

Content types live in code and in your migrations, not in the database. There is no screen for creating a content type at runtime.

Pick a guide

You want toGuide
Build your first content type, with its AdminCP screenFirst content type
Add drafts and a read-only public APIPublic API
Understand how public reads are cached and refreshedCaching
Give each record its own page with SEO metadataPublic pages
Control titles, descriptions, noindex and the sitemapSEO
Make records findable in the site searchSearch
Link records, group fields or repeat rowsRelations
Translate content into several languagesTranslations
Store and render formatted textRich text
Keep revisions, share previews or schedule publishingEditorial
Let several editors work on one record at the same timeLive editing
Change list columns, form sections or field componentsAdminCP
Read and write content from your own API routesServices
React to created, updated or published recordsEvents
Understand the generated tables and ship a schema changeDatabase
Check a content type before it goes liveProduction

Reference

  • Options: every defineContentType option and how the options depend on each other.
  • Fields: every field.* helper with its options, column type and form control.
  • Plugin files: the files and exports the app and the API read from your plugin.
  • Live editing API: the HTTP API and deployment requirements behind live editing.