Documentation

Publishing policies

Set per-container publishing rules in the VitNode Content Engine. Decide who may post in a forum, whether new posts and edits wait for approval, and how long authors may edit, with defineContentContainer policies and the AdminCP Publishing sheet.

Publishing policies let each container decide how members post in it: who may start, whether new records go live or wait for a moderator, whether edits to live records wait too, and how long authors may edit. One forum can be a free-for-all while the one next to it reviews every post.

This guide uses the Forum plugin: the forum.forums container collection, with topics (forum.topic) filed into forums and comments (forum.comment) living in their topic's forum.

Before you begin

You need a container collection and at least one content type with public write filed into it, through field.container() or a field.relation({ container: true }). Policies only govern the public write routes. Staff working in the AdminCP are not affected.

Turn on policies for the collection

Add policies to the collection's definition. defaults applies to every content type in it, and contentTypes overrides it for one content type:

plugins/forum/src/content/forums.ts
import { defineContentContainer, field } from "@vitnode/core/content";

export const forumContainers = defineContentContainer({
  id: "forum.forums",
  fields: {
    description: field.textarea({ maxLength: 500, nullable: true }),
  },
  hierarchy: { maxDepth: 4 },
  policies: {
    defaults: {
      publish: "immediate",
      edits: "immediate",
      authorEdit: "always",
    },
    contentTypes: {
      "forum.comment": { authorEdit: "window", authorEditMinutes: 30 },
    },
  },
  publicApi: { path: "forums", fields: ["description"] },
  admin: { path: "forum/forums" },
});

Topics go live straight away and stay editable by their authors. Comments go live too, but their authors can only edit them for 30 minutes.

policies: {} is enough to switch the feature on and leave every decision to the AdminCP. Without policies, the collection does not take part: its content types keep using publicWrite.create.status, owners edit forever, and can_edit stays unscoped.

Save

Policies are stored in a column core already has, so there is no migration. pnpm dev picks up the change when you save.

Turning policies on also gives each content type in the collection container-scoped can_edit and can_approve moderator permissions. Grant and label them as described in Container-scoped permissions.

Override one container in the AdminCP

Open the collection's screen, such as /admin/containers/forum/forums. In a forum's row menu, choose Publishing. The Publishing rules sheet has one section per content type, with these settings:

SettingKeyChoices
Who can startcreateMembers, Moderators only
New postspublishPublish immediately, Wait for approval
Edits to published postseditsApply immediately, Wait for approval
Author editingauthorEditAlways, Never, For a limited time
Editing windowauthorEditMinutesMinutes, used by For a limited time

Every setting starts on Inherit (currently: …), and the line below it says where the current value comes from: a parent forum, the collection's defaults or the content type's own default. For the "Help" forum, set New posts to Wait for approval for topics and choose Save rules.

The sheet needs the collection's can_view admin permission to open and can_edit to save. Saving emits content.container.updated with changedFields: ["policies"].

How a value is chosen

Each of the five keys is decided on its own. The engine takes the first layer that sets it:

  1. the record's container, for that content type;
  2. the nearest ancestor that sets it, walking up the parents;
  3. policies.contentTypes[contentTypeId] in the definition;
  4. policies.defaults in the definition;
  5. the fallback: create: "members", publish from publicWrite.create.status ("published" becomes "immediate", "draft" becomes "approve"), edits: "immediate", authorEdit: "always", authorEditMinutes: 60.

With "Help" set to Wait for approval for topics, a topic in its child forum "Bug reports" waits for approval too, while comments there still publish immediately: rules are per content type, and nobody changed the comment rules.

A key that is absent inherits. An explicit value is an override, even when it matches the parent today. If someone later relaxes "Help", a child that explicitly says Wait for approval keeps waiting. Choose Inherit to remove an override.

What members notice

RuleWhat happens on the public write routes
publish: "approve"A new record is stored as a draft, a submission opens, and the response carries approval. See Approvals
edits: "approve"An author's edit of a published record becomes a proposal. The live record does not change until a moderator approves
authorEdit: "never"Only moderators edit. The author gets 403 with the edit_window_closed issue
authorEdit: "window"The author edits until authorEditMinutes after the record's server createdAt, then gets 403 with edit_window_closed
create: "moderators"Only moderators holding can_edit in that container may create. Everyone else gets 403 with the moderators_only issue

Moderators are never held back by these rules. A can_edit holder edits any record in the container at any age, and a can_approve holder skips approval for their own posts. Root roles pass every check. The issue codes come in the usual rejection body, so translate them like any other issue.

Changing a policy never touches submissions that are already pending.

Check the result

Sign in as a regular member and create a topic in "Help". The response is a draft waiting for approval:

POST /api/@vitnode/forum/content/topics → 201
{
  "approval": {
    "id": 7,
    "kind": "create",
    "reason": null,
    "status": "pending",
    "submittedAt": "2026-10-13T09:12:44.512Z",
    "values": null
  },
  "id": 42,
  "slug": "the-editor-forgets-my-draft",
  "status": "draft",
  "publishedAt": null,
  "version": 1,
  "values": { "title": "The editor forgets my draft", "body": { "type": "doc", "content": [] }, "forum": 3 }
}

The topic is not on the public site yet. It appears in the ModCP approval queue for moderators who hold can_approve in "Help". A topic in a forum without overrides still answers with "status": "published" and "approval": null.

Every option, route and error is in the Publishing policies reference.