Replies
Let VitNode Content Engine comments answer each other. Raise thread.maxDepth, pass the same limit to useContentComments, and the shared comment section adds Reply, nests answers and keeps removed comments as placeholders.
Replies let a comment answer another comment, so a conversation can branch. The thread route already returns each top-level comment followed by every answer below it, and the shared section draws them as a tree. This page raises the depth limit and tells the section about it, which turns on Reply.
This continues the comment section from Comments. Replies work with or without Comment actions.
Raise the depth
Edit src/content/comment.ts. Export the limit, so the section uses the same number as the server. These are excerpts:
/** How deep replies nest. The section hides **Reply** at this depth. */
export const COMMENT_MAX_DEPTH = 4;
export const commentContentType = defineContentType({
// ...
thread: { parent: "parent", root: "article", maxDepth: 1 },
thread: { parent: "parent", root: "article", maxDepth: COMMENT_MAX_DEPTH },
});A top-level comment sits at depth 1, a reply to it at 2, and so on. With 4, a comment at depth 4 can't be answered. The limit is a rule of the API, not a database setting, so rebuild the plugin and skip migrating:
bun run build:pluginsTell the section
Pass the limit to useContentComments in src/pages/article-comments.tsx. This is an excerpt:
import { COMMENT_MAX_DEPTH } from "@/content/comment";
const comments = useContentComments({
...articleCommentsThread(articleId),
maxDepth: COMMENT_MAX_DEPTH, That is the whole change. create already sends parent: parentId, which is now the comment being answered instead of null. The section shows Reply under every comment above the limit, opens a composer under it, and draws replies indented below their parent. Below three levels it stops indenting, so deep branches stay readable on a phone.
Check the result
Open an article with a comment and sign in as a member:
- Click Reply under the comment, write an answer and click Post comment. Comment posted appears and the answer shows indented below the comment.
- Reply to the reply, and again, until a reply sits at depth 4. That reply has no Reply button.
- Reload. The tree comes back the same way.

Long conversations
- Pages are top-level comments. The section asks for 20 top-level comments at a time, and each comes with every reply below it, so replies never split across pages. Load more comments adds the next ones.
- Truncated pages. One page holds at most 500 comments in total. When deep replies don't fit, the section says that some deeper comments aren't shown, instead of pretending the conversation ends there.
- New top-level comments land at the end, because comments are oldest first. While pages remain, Load more comments reaches them.
- Permissions with Comment actions cover every loaded comment, in batches of 50, so a long thread keeps its menus.
Removed and hidden comments in a tree
- Deleted with replies. A comment deleted while it has replies stays as a [deleted] placeholder with no text and no author. It reads "Comment deleted by user" or "Comment removed by a moderator". Its replies keep their place, and you can still answer them.
- Hidden with replies. Readers who can't see a hidden comment get the same placeholder, so the branch below it stays readable. Its author and moderators see the real comment, marked Hidden. The section offers no Reply on a hidden comment.
- Removed without replies. The comment disappears. There's no branch below it to hold up.
The server keeps the tree valid on every write, in the AdminCP too: the parent must exist, be public and belong to the same article, a comment never answers itself or one of its own answers, and nothing nests deeper than maxDepth. A reply that breaks a rule answers 400, and the composer keeps its text.
Related
- Notifications: optional. Tell members about replies to their comments, sent by the server with no change to the section.
- Comments API: build your own tree layout with
ContentCommentsRoot, as the Blog plugin does with its connectors and collapsible branches. - thread reference: every
threadoption.