PhoenixKitComments
Resource-agnostic, polymorphic commenting module for PhoenixKit. Drop-in comments with unlimited nested threading, like/dislike reactions, moderation, and an admin dashboard.
Features
- Polymorphic comments — attach comments to any resource via
(resource_type, resource_uuid)with zero schema coupling - Unlimited nested threading — self-referencing
parent_uuidwith automatic depth tracking - Like/dislike reactions — one per user per comment, with denormalized counters and transaction-safe updates
- Moderation — optional approval workflow; comments start as
"pending"when moderation is enabled - Admin dashboard — search, filter by status/resource type, paginate, and perform bulk actions
- Auto-discovery — implements
PhoenixKit.Modulebehaviour; PhoenixKit finds it at startup with zero config - LiveView component — embeddable
CommentsComponentfor any page
Installation
Add phoenix_kit_comments to your dependencies in mix.exs:
def deps do
[
{:phoenix_kit_comments, "~> 0.1.0"}
]
endThen fetch dependencies:
mix deps.getNote: For development or if not yet published to Hex, you can use:
{:phoenix_kit_comments, github: "mdon/phoenix_kit_comments"}
PhoenixKit auto-discovers the module at startup — no additional configuration needed.
Quick Start
-
Add the dependency to
mix.exs -
Run
mix deps.get -
Enable the module in admin settings (
comments_enabled: true) -
Embed the
CommentsComponentin your LiveViews
Usage
Embedding comments on a page
Use the CommentsComponent LiveComponent in any LiveView:
<.live_component
module={PhoenixKitComments.Web.CommentsComponent}
id="comments"
resource_type="post"
resource_uuid={@post.uuid}
current_user={@current_user}
/>Resource handler callbacks
Modules that consume comments can register handlers to receive lifecycle notifications:
# config/config.exs
config :phoenix_kit, :comment_resource_handlers, %{
"post" => PhoenixKitPosts,
"entity" => PhoenixKitEntities
}Handler modules can implement:
on_comment_created/3— called after a comment is createdon_comment_deleted/3— called after a comment is deletedresolve_comment_resources/1— returns%{uuid => %{title: ..., path: ...}}for admin display
Settings
| Key | Type | Default | Description |
|---|---|---|---|
comments_enabled | boolean | false | Enable/disable the module |
comments_moderation | boolean | false | Require approval for new comments |
comments_max_depth | integer | 10 | Maximum thread nesting level |
comments_max_length | integer | 10000 | Maximum comment length (characters) |
Moderation Workflow
When comments_moderation is enabled:
-
New comments start with status
"pending" -
Admins can approve (set to
"published") or reject (set to"hidden") - Approved comments become visible to all users
- Rejected comments remain hidden but are not deleted
Permissions
The module declares permissions via permission_metadata/0:
:admin_comments— Access to moderation dashboard:admin_settings_comments— Access to settings page
Use Scope.has_module_access?/2 to check permissions in your application.
CSS Requirements
For Tailwind CSS users: ensure phoenix_kit_comments is listed in your tailwind.config.js sources:
module.exports = {
content: [
// ...
"./deps/phoenix_kit_comments/**/*.{heex,ex}",
// ...
]
}Architecture
lib/
phoenix_kit_comments.ex # Context + PhoenixKit.Module behaviour
phoenix_kit_comments/
schemas/
comment.ex # Polymorphic comment schema with threading
comment_like.ex # Like tracking (unique per user per comment)
comment_dislike.ex # Dislike tracking (unique per user per comment)
web/
comments_component.ex # Embeddable LiveComponent
index.ex # Admin moderation dashboard
settings.ex # Admin settings pageComment statuses
| Status | Description |
|---|---|
"published" | Visible to all (default when moderation is off) |
"pending" | Awaiting moderator approval |
"hidden" | Hidden by a moderator |
"deleted" | Soft-deleted |
Database tables
phoenix_kit_comments— comment records (UUIDv7 primary keys)phoenix_kit_comments_likes— like records with unique(comment_uuid, user_uuid)constraintphoenix_kit_comments_dislikes— dislike records with unique(comment_uuid, user_uuid)constraint
Development
mix deps.get # Install dependencies
mix test # Run tests
mix format # Format code
mix credo # Static analysis
mix dialyzer # Type checking
mix docs # Generate documentationTroubleshooting
Comments not appearing
-
Verify
comments_enabledistruein settings - Check that the resource type matches exactly (case-sensitive)
- Ensure the current user is authenticated and passed to the component
CSS classes missing
-
Add
phoenix_kit_commentsto your Tailwind content sources -
Run
mix assets.deployto rebuild CSS
Permission denied errors
-
Verify the user has the
:admin_commentspermission -
Check that
Scope.has_module_access?/2returnstrue
License
MIT — see LICENSE for details.