Open source
Comments for Laravel
composer require roundly-consulting/comments-for-laravelOverview
Polymorphic comments for Laravel. Any Eloquent model can receive comments and any model can write them — with threaded replies, a pending/approved/hidden moderation workflow, a blocklist filter, @mentions, thread locks, per-comment metadata and a discoverable Comments facade. Likes, report-a-comment moderation and media attachments come built in through sibling Roundly packages. MIT-licensed, with no third-party runtime dependencies beyond Laravel and those packages.
What you get
Comment on anything
Any model receives comments and any model writes them — plus anonymous guest comments, all in one polymorphic table.
Threaded replies
Replies link to their parent and stay on the root subject, with a depth limit that also bounds eager-loading.
Moderation built in
Pending, approved and hidden states, an approval queue, bulk moderation and a word or regex blocklist.
Likes & reports
Rank threads by most-liked or trending, and auto-hide comments once a report is upheld or a threshold is crossed.
Attachments & inline media
A private attachments bucket per comment, with [media:UUID] tokens rendered as responsive images or links.
Mentions & locks
@handles parsed and resolved to your models, plus locks for a whole subject or the thread under one comment.
Metadata & merges
Tag each comment with your own namespaced metadata and filter by it, and move a whole discussion in one call when two records merge.
Facade, DI or actions
One Comments facade, the injectable CommentsManager or single actions — and a recording Comments::fake() plus a drop-in JSON resource.
Documentation
Installation
Install via Composer, publish and run the migrations — the sibling packages’ too — upgrade from 1.0, and optionally publish config and translations.
Configuration
Every config key and its default — model, key type, approval, limits, blocklist, mentions, authorization, author resource, auto-moderation and media.
Preparing your models
Add HasComments to models that receive comments and GivesComments to authors — or swap in your own Comment model.
The Comments facade
The whole API in one place — a fluent write builder, edits, moderation, site-wide and scoped queries, locks, transfers, a blocklist check and fake().
DI and actions
Inject CommentsManager for the same API without static calls, or run one of eleven action classes directly from a job or your own action.
Writing comments
Write comments through the fluent Comments facade, a typed DTO or the author trait — with body, lock and blocklist checks on every write.
Editing, deleting & restoring
Edit a comment’s body, soft-delete and restore it — edits are re-validated, lock-checked and re-scanned for mentions.
Threaded replies
Replies link to their parent and stay on the root subject; depth is capped by max_depth, which also bounds eager-loading.
Reading & counting comments
Read comments through model relations or the fluent CommentQuery — filters, ordering, pagination, escape hatches and N+1-free counts.
Comment metadata
Attach your own namespaced metadata to each comment, read it back by dot path and filter comments by it — the same on SQLite, PostgreSQL and MySQL.
Moderation
Pending, approved and hidden states, an optional approval queue, moderation scopes and bulk approve, hide or delete.
Spam & blocklist filter
Reject, hold or hide comments that match banned words or regular expressions, or check a body yourself — no external service needed.
@mentions
Parse @handles on every write and edit, store them, and resolve them to your models — CommentMentioned fires once per person, after approval.
Locking threads
Lock a subject’s whole comment section, or the whole thread under one comment, to stop new and edited comments.
Transferring comments
Move a whole discussion from one record to another when duplicates merge — replies, held and deleted comments included, with likes and attachments.
Likes & ranking
Like, upvote and react to comments via Likes for Laravel, then rank threads by most-liked or trending with per-viewer state in one query.
Reporting & auto-moderation
Let users and guests report comments via Reports for Laravel, build moderation queues, and auto-hide comments on upheld reports.
Attachments & inline media
Attach files to a comment’s own bucket via Media Library for Laravel, and embed them in the body with [media:UUID] tokens.
Authorization
Opt in to gate every mutation — writes, edits, deletes, restores, moderation, locks and transfers — through a Comment policy built on the bundled one.
API resources
Return comments as JSON with CommentResource — nested replies, author and status, plus likes and attachments when loaded.
Events
Nine events — created, updated, deleted, approved, hidden, thread locked and unlocked, mentioned and transferred — for notifications and audits.
Exceptions & messages
Every failure is a typed CommentsException with a translatable message — catch the base class, or handle each case.
Testing
Comments::fake() records every mutation while still running it, with an assert per verb — plus factories that need no setup and AssertsComments.
Requirements
PHP 8.4+, Laravel 12 or 13, and the sibling Roundly packages Composer installs for you.
Show your open-source love
This package is free and MIT-licensed. If it saves you time, a one-off donation or a Patreon membership keeps it maintained, tested and documented.
More ways to support, including cryptoBy donating, you agree to our donation terms.
Want this built into your product?
We integrate our packages into custom Laravel and AI builds. Tell us what you're working on and we'll reply within 48 hours.