Search iThub

Search tools, categories and collections. Type at least two characters.

Explore all tools
↑ ↓ to explore resultsEnter to open · Esc to close

Payload Comments

MIT-licensed Payload CMS 3 plugin for anonymous comments, reactions, moderation and threaded replies

Visit website Save

Payload Comments (@navanem/payload-comments) adds anonymous comments, emoji reactions, optional pre-publish moderation and up to three levels of replies to Payload CMS 3, with a React component, REST endpoints and an admin statistics view.

Pricing
Open source
Deployment
Self-hosted
Platforms
Web
1stars0forks
64views
Updated

What is Payload Comments?

Payload Comments is an open-source plugin for Payload CMS 3.x, published under the package name @navanem/payload-comments. It adds anonymous comments, emoji reactions on comments, optional approval before publication and nested replies up to three levels deep to any Payload collection that the site owner enables. Comment bodies accept a limited Markdown subset, and raw HTML is never rendered. The plugin is written in TypeScript and licensed under MIT.

The plugin is built and maintained by Navanem, a web agency in Geneva and Lausanne, Switzerland. Its project page describes it as a plugin for discussions beneath content and for the people who moderate them, and the README states that it runs in production on navanem.com. The source, issue tracker and release history are on GitHub.

Distribution is source based. The README lists pnpm add @navanem/payload-comments and, until the package is published to the npm registry, pnpm add github:navanem/payload-comments. The plugin can also be vendored into a project under src/plugins/payload-comments. payload (3.88 or later according to the current package.json), react and react-dom 18 or 19 are peer dependencies; the runtime dependencies are react-markdown and remark-gfm, and the engines field requires Node.js 18.20 or later.

The latest release is v0.4.1, published on September 6, 2026. It updated Payload, React, Vitest, TypeScript and related tooling, refreshed vulnerable transitive dependencies, and added CI, Dependabot, contribution, security and protected-branch configuration. Version 0.4.0 (June 2026) added a Thread column to the moderation list. Version 0.3.0 introduced Markdown comment bodies and a runtime approval switch, and 0.2.0 added the Comments Settings global and the Comment Statistics admin view. The full history is in the changelog.

Internally, commentsPlugin() injects two collections, comments and comment-reactions, one global and three public endpoints under /api/comments-api/. Data lives in whatever database adapter the host Payload project uses; the development app in the repository uses the SQLite adapter. IP addresses and browser fingerprints are stored only as salted SHA-256 hashes. The moderation documentation describes the built-in anti-spam measures as deterrents rather than a guarantee and mentions a CAPTCHA or WAF for high-traffic sites. The plugin has no hosted service, no user accounts for commenters and no pricing. Related listings: Payload CMS and Payload Contact, another Navanem plugin for Payload 3.

Key capabilities

  • Anonymous comment submission Visitors post with a display name, an email address that is optional by default (requireEmail can make it mandatory) and a mood emoji. There are no commenter accounts or logins. The email is stored for moderation but is never returned by the public API or shown to unauthenticated users.
  • Markdown comment bodies Since 0.3.0 comments render a safe Markdown subset through react-markdown and remark-gfm: bold, italic, strikethrough, inline and block code, links, lists and blockquotes. Raw HTML is never rendered. Links are forced to open in a new tab with rel="noopener noreferrer nofollow ugc". Custom front ends receive the raw Markdown string and need their own safe renderer.
  • Threaded replies Replies can be nested up to three levels, enforced on the server. The maxDepth option accepts 1, 2 or 3, and the front-end component takes a matching prop so the client and server limits agree.
  • Reactions on comments Readers can react to existing comments with a configurable emoji set; six reactions are defined by default. Each reaction has a stored key, an emoji and an accessibility label. Posting the same emoji again from the same identity removes it. Reactions are not moderated and are de-duplicated per visitor using the hashed IP and fingerprint.
  • Pre-publish moderation With requireApproval: true, which is the default, new comments start as pending and stay hidden until an admin approves them. Statuses are pending, approved, spam and trash, and only approved comments are returned by the public tree endpoint. With approval disabled, comments are published immediately and can still be moved to spam or trash.
  • Runtime approval switch The Comments Settings global has a Require approval checkbox seeded from the requireApproval option. The submit flow reads it on every request, so moderation can be turned on or off without a redeploy.
  • Per-collection on and off toggle enabledCollections defines which collections can receive comments, and the Comments Settings global enables or disables each of them at runtime. A disabled collection rejects new submissions and the widget shows a closed notice; existing comments remain in the database and visible in the admin. The global fails open: if it has never been saved, every configured collection counts as enabled.
  • Moderation queue in the Payload admin Comments are a standard Payload collection, so the list view with its filters and bulk actions serves as the moderation queue. Since 0.4.0 the list shows a Thread column (top-level or reply to an author) and the target document. The column is a virtual field computed only for authenticated admin reads, with no database column or migration.
  • Comment Statistics view An admin view at /admin/comments-statistics shows totals by status, reaction count, a per-day rate, breakdowns per collection and per mood, and a recent-comments table. It filters by collection, status and period, queries data on the server and renders only for an authenticated admin. A navigation link is registered through afterNavLinks for the default Payload nav.
  • Built-in anti-spam The plugin includes a honeypot field, a per-IP sliding-window rate limit (default 5 submissions per 60 seconds), minimum and maximum content length (2 and 2000 characters by default) and an optional blockLinks setting that rejects comments containing URLs.
  • Hashed visitor identity IP addresses and browser fingerprints are never stored in clear text. The plugin keeps salted SHA-256 hashes for rate limiting and reaction de-duplication. The salt comes from the ipSalt option or the COMMENTS_IP_SALT environment variable, and the documentation asks for a stable secret value.
  • Bundled React component <Comments /> is exported from @navanem/payload-comments/client. It takes relationTo, docId, an optional serverURL for a Payload server on another origin, and props that mirror the server settings for reactions, email and depth. Styling uses CSS Modules with CSS variables such as --pc-accent and --pc-border.
  • Public REST API Three endpoints support custom interfaces: GET /api/comments-api/tree returns approved comments as a nested tree with emails stripped, POST /api/comments-api/submit creates a comment, and POST /api/comments-api/<commentId>/react toggles a reaction. Requests and responses are documented in the front-end integration guide.
  • Configurable slugs and options The configuration reference lists the options: collection slugs for comments and reactions, reaction set, length limits, rate limit window, link blocking, salt and a disabled flag that registers the collections but skips the endpoints.
  • Installation Add the package with pnpm from the npm name or directly from GitHub, register commentsPlugin() in payload.config.ts, set COMMENTS_IP_SALT, and place the component on a page. When the plugin is vendored under src/plugins/payload-comments, the admin import map must resolve @/plugins/payload-comments/components/*, for example by running payload generate:importmap.
  • Tests and CI The repository includes Vitest tests for access control, hooks, the comment tree, reactions, submission, client identity, hashing, rate limiting and content validation, plus a GitHub Actions CI workflow and Dependabot configuration added in 0.4.1.
Advertisements

Where Payload Comments fits

Comments under blog posts or articles

A Payload site lists its post or page collections in enabledCollections and renders <Comments relationTo="posts" docId={post.id} /> on the article template. Readers see approved comments with their Markdown bodies, mood emoji, date, reactions and a reply button, and a composer for name, optional email, text and mood. The README describes this setup on navanem.com.

Moderated discussion with an approval queue

With approval required, every submission arrives as pending. Editors filter the Comments collection by status in the Payload admin, open an entry to see author, email, mood, related document, parent comment and hashed identifiers, and set it to approved, spam or trash. Approval publishes the comment immediately. The moderation guide documents the statuses and the runtime switch.

Closing comments on a collection

Editors can disable commenting for a single collection from the Comments Settings global without a deployment. New submissions to that collection are rejected and the widget displays a closed notice, while the existing comments stay stored and visible to admins. The same global switches mandatory approval on or off.

Custom front end on the REST API

Sites that do not use React, or need their own markup, can call the tree, submit and react endpoints directly. The submit body carries content, author name and email, mood, a fingerprint string, an empty honeypot field, the related document and an optional parent. The tree response contains only approved comments with emails removed, and the stored content is raw Markdown that the client renders itself.

Reviewing comment activity

The Comment Statistics view in the admin gives counts by status, reaction totals, a per-day rate, per-collection and per-mood breakdowns and a recent-comments table, filterable by collection, status and period. Data is queried on the server and shown only to an authenticated admin.

Headless or cross-origin setups

When the Payload server runs on a different origin from the website, the component accepts a serverURL prop pointing to it. The props for reactions, required email and maximum depth must mirror the server configuration, as stated in the integration guide.

Install

pnpm add github:navanem/payload-comments

Reviews of Payload Comments

No reviews yet

Be the first to share your experience with Payload Comments.

Loading review form…

Related to Payload Comments

Compare Payload Comments with these tools →