# _development_cache

id: docs/1.getting-started/2.installation.md
checksum: 4a7112280e24ae38b76082c984d9fb46
__hash__: dwuGOaha9g0LBC-fXmevJz8Csf229TI_LVXFGNepSMY
value:
{"id":"docs/1.getting-started/2.installation.md","title":"Installation","description":"Get started with Comments in minutes.","navigation":{"icon":"i-lucide-download"},"seo":{"description":"Install Comments and add commenting to your Filament resources.","ogImage":"/preview.png","title":"Installation"},"body":{"type":"minimark","value":[["h2",{"id":"requirements"},"Requirements"],["ul",{},["li",{},["strong",{},"PHP:"]," 8.2+"],["li",{},["strong",{},"Laravel:"]," 12+"],["li",{},["strong",{},"Filament:"]," 4.x / 5.x"],["li",{},["strong",{},"Livewire:"]," 3.5+ / 4.x"]],["h2",{"id":"quick-setup"},"Quick Setup"],["steps",{},["h3",{"id":"install-package"},"Install Package"],["pre",{"className":"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","code":"composer require relaticle/comments\n","filename":"Terminal","language":"bash","meta":"","style":""},["code",{"__ignoreMap":""},["span",{"class":"line","line":1},["span",{"class":"sBMFI"},"composer"],["span",{"class":"sfazB"}," require"],["span",{"class":"sfazB"}," relaticle/comments\n"]]]],["h3",{"id":"publish-and-run-migrations"},"Publish and Run Migrations"],["pre",{"className":"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","code":"php artisan vendor:publish --tag=comments-migrations\nphp artisan migrate\n","filename":"Terminal","language":"bash","meta":"","style":""},["code",{"__ignoreMap":""},["span",{"class":"line","line":1},["span",{"class":"sBMFI"},"php"],["span",{"class":"sfazB"}," artisan"],["span",{"class":"sfazB"}," vendor:publish"],["span",{"class":"sfazB"}," --tag=comments-migrations\n"]],["span",{"class":"line","line":2},["span",{"class":"sBMFI"},"php"],["span",{"class":"sfazB"}," artisan"],["span",{"class":"sfazB"}," migrate\n"]]]],["h3",{"id":"include-css-assets"},"Include CSS Assets"],["p",{},"Prerequisite: You need a custom Filament theme to include the Comments styles."],["alert",{"type":"warning"},"If you haven't set up a custom theme for Filament, follow the ",["a",{"href":"https://filamentphp.com/docs/5.x/styling/overview#creating-a-custom-theme","rel":["nofollow"]},"Filament Docs"]," first."],["p",{},"Add the plugin's views to your theme CSS file:"],["pre",{"className":"language-css shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","code":"@source \"../../../../vendor/relaticle/comments/resources/views/**/*.blade.php\";\n","filename":"resources/css/filament/admin/theme.css","language":"css","meta":"","style":""},["code",{"__ignoreMap":""},["span",{"class":"line","line":1},["span",{"class":"s7zQu"},"@source"],["span",{"class":"sTEyZ"}," \"../../../../vendor/relaticle/comments/resources/views/**/*.blade.php\""],["span",{"class":"sMK4o"},";\n"]]]],["h3",{"id":"register-the-plugin"},"Register the Plugin"],["pre",{"className":"language-php shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","code":"use Relaticle\\Comments\\CommentsPlugin;\n\npublic function panel(Panel $panel): Panel\n{\n    return $panel\n        ->plugins([\n            CommentsPlugin::make(),\n        ]);\n}\n","filename":"AdminPanelProvider.php","language":"php","meta":"","style":""},["code",{"__ignoreMap":""},["span",{"class":"line","line":1},["span",{"class":"sbssI"},"use"],["span",{"class":"sTEyZ"}," Relaticle"],["span",{"class":"sMK4o"},"\\"],["span",{"class":"sTEyZ"},"Comments"],["span",{"class":"sMK4o"},"\\"],["span",{"class":"sTEyZ"},"CommentsPlugin"],["span",{"class":"sMK4o"},";\n"]],["span",{"class":"line","line":2},["span",{"emptyLinePlaceholder":true},"\n"]],["span",{"class":"line","line":3},["span",{"class":"spNyl"},"public"],["span",{"class":"spNyl"}," function"],["span",{"class":"s2Zo4"}," panel"],["span",{"class":"sMK4o"},"("],["span",{"class":"sBMFI"},"Panel"],["span",{"class":"sMK4o"}," $"],["span",{"class":"sTEyZ"},"panel"],["span",{"class":"sMK4o"},"):"],["span",{"class":"sBMFI"}," Panel\n"]],["span",{"class":"line","line":4},["span",{"class":"sMK4o"},"{\n"]],["span",{"class":"line","line":5},["span",{"class":"s7zQu"},"    return"],["span",{"class":"sMK4o"}," $"],["span",{"class":"sTEyZ"},"panel\n"]],["span",{"class":"line","line":6},["span",{"class":"sMK4o"},"        ->"],["span",{"class":"s2Zo4"},"plugins"],["span",{"class":"sMK4o"},"([\n"]],["span",{"class":"line","line":7},["span",{"class":"sBMFI"},"            CommentsPlugin"],["span",{"class":"sMK4o"},"::"],["span",{"class":"s2Zo4"},"make"],["span",{"class":"sMK4o"},"(),\n"]],["span",{"class":"line","line":8},["span",{"class":"sMK4o"},"        ]);\n"]],["span",{"class":"line","line":9},["span",{"class":"sMK4o"},"}\n"]]]],["h3",{"id":"set-up-your-models"},"Set Up Your Models"],["p",{},"Add the ",["code",{},"HasComments"]," trait to any model you want to comment on:"],["pre",{"className":"language-php shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","code":"use Relaticle\\Comments\\Concerns\\HasComments;\nuse Relaticle\\Comments\\Contracts\\Commentable;\n\nclass Project extends Model implements Commentable\n{\n    use HasComments;\n}\n","filename":"app/Models/Project.php","language":"php","meta":"","style":""},["code",{"__ignoreMap":""},["span",{"class":"line","line":1},["span",{"class":"sbssI"},"use"],["span",{"class":"sTEyZ"}," Relaticle"],["span",{"class":"sMK4o"},"\\"],["span",{"class":"sTEyZ"},"Comments"],["span",{"class":"sMK4o"},"\\"],["span",{"class":"sTEyZ"},"Concerns"],["span",{"class":"sMK4o"},"\\"],["span",{"class":"sTEyZ"},"HasComments"],["span",{"class":"sMK4o"},";\n"]],["span",{"class":"line","line":2},["span",{"class":"sbssI"},"use"],["span",{"class":"sTEyZ"}," Relaticle"],["span",{"class":"sMK4o"},"\\"],["span",{"class":"sTEyZ"},"Comments"],["span",{"class":"sMK4o"},"\\"],["span",{"class":"sTEyZ"},"Contracts"],["span",{"class":"sMK4o"},"\\"],["span",{"class":"sTEyZ"},"Commentable"],["span",{"class":"sMK4o"},";\n"]],["span",{"class":"line","line":3},["span",{"emptyLinePlaceholder":true},"\n"]],["span",{"class":"line","line":4},["span",{"class":"spNyl"},"class"],["span",{"class":"sBMFI"}," Project"],["span",{"class":"spNyl"}," extends"],["span",{"class":"sBMFI"}," Model"],["span",{"class":"spNyl"}," implements"],["span",{"class":"sBMFI"}," Commentable\n"]],["span",{"class":"line","line":5},["span",{"class":"sMK4o"},"{\n"]],["span",{"class":"line","line":6},["span",{"class":"sbssI"},"    use"],["span",{"class":"sTEyZ"}," HasComments"],["span",{"class":"sMK4o"},";\n"]],["span",{"class":"line","line":7},["span",{"class":"sMK4o"},"}\n"]]]],["p",{},"Add the ",["code",{},"IsCommenter"]," trait to your User model:"],["pre",{"className":"language-php shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","code":"use Relaticle\\Comments\\Concerns\\IsCommenter;\nuse Relaticle\\Comments\\Contracts\\Commenter;\n\nclass User extends Authenticatable implements Commenter\n{\n    use IsCommenter;\n}\n","filename":"app/Models/User.php","language":"php","meta":"","style":""},["code",{"__ignoreMap":""},["span",{"class":"line","line":1},["span",{"class":"sbssI"},"use"],["span",{"class":"sTEyZ"}," Relaticle"],["span",{"class":"sMK4o"},"\\"],["span",{"class":"sTEyZ"},"Comments"],["span",{"class":"sMK4o"},"\\"],["span",{"class":"sTEyZ"},"Concerns"],["span",{"class":"sMK4o"},"\\"],["span",{"class":"sTEyZ"},"IsCommenter"],["span",{"class":"sMK4o"},";\n"]],["span",{"class":"line","line":2},["span",{"class":"sbssI"},"use"],["span",{"class":"sTEyZ"}," Relaticle"],["span",{"class":"sMK4o"},"\\"],["span",{"class":"sTEyZ"},"Comments"],["span",{"class":"sMK4o"},"\\"],["span",{"class":"sTEyZ"},"Contracts"],["span",{"class":"sMK4o"},"\\"],["span",{"class":"sTEyZ"},"Commenter"],["span",{"class":"sMK4o"},";\n"]],["span",{"class":"line","line":3},["span",{"emptyLinePlaceholder":true},"\n"]],["span",{"class":"line","line":4},["span",{"class":"spNyl"},"class"],["span",{"class":"sBMFI"}," User"],["span",{"class":"spNyl"}," extends"],["span",{"class":"sBMFI"}," Authenticatable"],["span",{"class":"spNyl"}," implements"],["span",{"class":"sBMFI"}," Commenter\n"]],["span",{"class":"line","line":5},["span",{"class":"sMK4o"},"{\n"]],["span",{"class":"line","line":6},["span",{"class":"sbssI"},"    use"],["span",{"class":"sTEyZ"}," IsCommenter"],["span",{"class":"sMK4o"},";\n"]],["span",{"class":"line","line":7},["span",{"class":"sMK4o"},"}\n"]]]],["h3",{"id":"add-to-your-resources"},"Add to Your Resources"],["p",{},"Use the slide-over action on view or edit pages:"],["pre",{"className":"language-php shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","code":"use Relaticle\\Comments\\Filament\\Actions\\CommentsAction;\n\nprotected function getHeaderActions(): array\n{\n    return [\n        CommentsAction::make(),\n    ];\n}\n","filename":"app/Filament/Resources/ProjectResource/Pages/ViewProject.php","language":"php","meta":"","style":""},["code",{"__ignoreMap":""},["span",{"class":"line","line":1},["span",{"class":"sbssI"},"use"],["span",{"class":"sTEyZ"}," Relaticle"],["span",{"class":"sMK4o"},"\\"],["span",{"class":"sTEyZ"},"Comments"],["span",{"class":"sMK4o"},"\\"],["span",{"class":"sTEyZ"},"Filament"],["span",{"class":"sMK4o"},"\\"],["span",{"class":"sTEyZ"},"Actions"],["span",{"class":"sMK4o"},"\\"],["span",{"class":"sTEyZ"},"CommentsAction"],["span",{"class":"sMK4o"},";\n"]],["span",{"class":"line","line":2},["span",{"emptyLinePlaceholder":true},"\n"]],["span",{"class":"line","line":3},["span",{"class":"spNyl"},"protected"],["span",{"class":"spNyl"}," function"],["span",{"class":"s2Zo4"}," getHeaderActions"],["span",{"class":"sMK4o"},"():"],["span",{"class":"sbssI"}," array\n"]],["span",{"class":"line","line":4},["span",{"class":"sMK4o"},"{\n"]],["span",{"class":"line","line":5},["span",{"class":"s7zQu"},"    return"],["span",{"class":"sMK4o"}," [\n"]],["span",{"class":"line","line":6},["span",{"class":"sBMFI"},"        CommentsAction"],["span",{"class":"sMK4o"},"::"],["span",{"class":"s2Zo4"},"make"],["span",{"class":"sMK4o"},"(),\n"]],["span",{"class":"line","line":7},["span",{"class":"sMK4o"},"    ];\n"]],["span",{"class":"line","line":8},["span",{"class":"sMK4o"},"}\n"]]]]],["p",{},["strong",{},"Done!"]," Visit your Filament panel to see comments in action."],["h2",{"id":"optional-configuration"},"Optional Configuration"],["table",{},["thead",{},["tr",{},["th",{},"Command"],["th",{},"Action"]]],["tbody",{},["tr",{},["td",{},["code",{},"php artisan vendor:publish --tag=comments-config"]],["td",{},"Publish the configuration file"]],["tr",{},["td",{},["code",{},"php artisan vendor:publish --tag=comments-views"]],["td",{},"Publish the Blade views for customization"]],["tr",{},["td",{},["code",{},"php artisan vendor:publish --tag=comments-translations"]],["td",{},"Publish the translation files"]]]],["style",{},"html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}"]],"toc":{"title":"","searchDepth":2,"depth":2,"links":[{"id":"requirements","depth":2,"text":"Requirements"},{"id":"quick-setup","depth":2,"text":"Quick Setup","children":[{"id":"install-package","depth":3,"text":"Install Package"},{"id":"publish-and-run-migrations","depth":3,"text":"Publish and Run Migrations"},{"id":"include-css-assets","depth":3,"text":"Include CSS Assets"},{"id":"register-the-plugin","depth":3,"text":"Register the Plugin"},{"id":"set-up-your-models","depth":3,"text":"Set Up Your Models"},{"id":"add-to-your-resources","depth":3,"text":"Add to Your Resources"}]},{"id":"optional-configuration","depth":2,"text":"Optional Configuration"}]}},"meta":{},"__metadata":{},"path":"/getting-started/installation","stem":"1.getting-started/2.installation","extension":"md"}


id: docs/1.getting-started/.navigation.yml
checksum: caf135037f6ba2b11f3705b2f9600cf3
__hash__: Vwd30tIybGSZ-bCnSmEPhKyHTmMsuZha_ydr2sX9zqs
value:
{"id":"docs/1.getting-started/.navigation.yml","title":"Getting Started","meta":{"icon":false},"__metadata":{},"seo":{"title":"Getting Started"},"path":"/getting-started/.navigation","stem":"1.getting-started/.navigation","extension":"yml"}


id: docs/1.getting-started/3.upgrading.md
checksum: f957f1eeb8ccf8bd57a68ec86072b7e4
__hash__: qWmV7_p8DvWDEgmteTIJPzqTRRhkmz_BAVjiPbEt1Zc
value:
{"id":"docs/1.getting-started/3.upgrading.md","title":"Upgrading","description":"Upgrade guide for Comments.","navigation":{"icon":"i-lucide-arrow-up-circle"},"seo":{"description":"How to upgrade Comments between versions.","title":"Upgrading"},"body":{"type":"minimark","value":[["h2",{"id":"_1x"},"1.x"],["p",{},"This is the initial release of Comments. Future upgrade guides will be documented here as new versions are released."]],"toc":{"title":"","searchDepth":2,"depth":2,"links":[{"id":"_1x","depth":2,"text":"1.x"}]}},"meta":{},"__metadata":{},"path":"/getting-started/upgrading","stem":"1.getting-started/3.upgrading","extension":"md"}


id: docs/4.community/1.contributing.md
checksum: c07c4bc354e6c3927e93b170cda75da0
__hash__: 5sJUYLXOU0SiMeE11gHL9PFXdSvGo1Ojn8TorI_sU6s
value:
{"id":"docs/4.community/1.contributing.md","title":"Contributing","description":"How to contribute to Comments","navigation":{"icon":"i-lucide-heart-handshake"},"body":{"type":"minimark","value":[["h2",{"id":"quick-start"},"Quick Start"],["ol",{},["li",{},["strong",{},"Fork"]," the repository"],["li",{},["strong",{},"Create"]," a feature branch"],["li",{},["strong",{},"Make"]," your changes"],["li",{},["strong",{},"Run"]," tests: ",["code",{},"composer test"]],["li",{},["strong",{},"Submit"]," a pull request"]],["h2",{"id":"guidelines"},"Guidelines"],["ul",{},["li",{},"Follow the existing code style"],["li",{},"Add tests for new features"],["li",{},"Update documentation as needed"],["li",{},"One feature per pull request"]],["h2",{"id":"development-commands"},"Development Commands"],["pre",{"className":"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","code":"# Run tests\ncomposer test\n\n# Format code\ncomposer pint\n\n# Static analysis\ncomposer analyse\n","language":"bash","meta":"","style":""},["code",{"__ignoreMap":""},["span",{"class":"line","line":1},["span",{"class":"sHwdD"},"# Run tests\n"]],["span",{"class":"line","line":2},["span",{"class":"sBMFI"},"composer"],["span",{"class":"sfazB"}," test\n"]],["span",{"class":"line","line":3},["span",{"emptyLinePlaceholder":true},"\n"]],["span",{"class":"line","line":4},["span",{"class":"sHwdD"},"# Format code\n"]],["span",{"class":"line","line":5},["span",{"class":"sBMFI"},"composer"],["span",{"class":"sfazB"}," pint\n"]],["span",{"class":"line","line":6},["span",{"emptyLinePlaceholder":true},"\n"]],["span",{"class":"line","line":7},["span",{"class":"sHwdD"},"# Static analysis\n"]],["span",{"class":"line","line":8},["span",{"class":"sBMFI"},"composer"],["span",{"class":"sfazB"}," analyse\n"]]]],["h2",{"id":"need-help"},"Need Help?"],["ul",{},["li",{},["a",{"href":"https://github.com/relaticle/comments/issues","rel":["nofollow"]},"Open an issue"]," for bugs or questions"],["li",{},"Check ",["a",{"href":"https://github.com/relaticle/comments/issues","rel":["nofollow"]},"existing issues"]," first"]],["style",{},"html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}"]],"toc":{"title":"","searchDepth":2,"depth":2,"links":[{"id":"quick-start","depth":2,"text":"Quick Start"},{"id":"guidelines","depth":2,"text":"Guidelines"},{"id":"development-commands","depth":2,"text":"Development Commands"},{"id":"need-help","depth":2,"text":"Need Help?"}]}},"meta":{},"__metadata":{},"seo":{"title":"Contributing","description":"How to contribute to Comments"},"path":"/community/contributing","stem":"4.community/1.contributing","extension":"md"}


id: docs/1.getting-started/1.introduction.md
checksum: a642c31b3eec578ca3292b4012517a80
__hash__: DiQPTvhshlKDazc5Vd329xq2xiCBV6J3JbTQ0X4PbgM
value:
{"id":"docs/1.getting-started/1.introduction.md","title":"Introduction","description":"A full-featured commenting system for Filament panels.","navigation":{"icon":"i-lucide-home"},"seo":{"title":"Introduction","description":"Learn about Comments - a full-featured commenting system for Filament panels with threaded replies, @mentions, emoji reactions, and real-time updates.","ogImage":"/preview.png"},"body":{"type":"minimark","value":[["p",{},"Welcome to ",["strong",{},"Comments"],", a powerful Laravel package that adds a full-featured commenting system to any Filament panel."],["h2",{"id":"what-is-comments"},"What is Comments?"],["p",{},"Comments provides polymorphic commenting on any Eloquent model with deep Filament integration. Add threaded discussions, @mentions, emoji reactions, file attachments, and real-time notifications to your admin panel with minimal setup."],["h2",{"id":"why-choose-comments"},"Why Choose Comments?"],["card-group",{},["card",{"icon":"i-lucide-messages-square","title":"Threaded Discussions"},"Nested replies with configurable depth limits keep conversations organized and easy to follow."],["card",{"icon":"i-lucide-clock","title":"Quick Setup"},"Add traits to your models, register the plugin, and you have a working comment system in minutes."],["card",{"icon":"i-lucide-puzzle","title":"3 Integration Patterns"},"Use as a slide-over action, table row action, or inline infolist entry - whatever fits your resource."],["card",{"icon":"i-lucide-bell","title":"Built-in Notifications"},"Database and mail notifications with subscription management and auto-subscribe for authors and mentioned users."]]],"toc":{"title":"","searchDepth":2,"depth":2,"links":[{"id":"what-is-comments","depth":2,"text":"What is Comments?"},{"id":"why-choose-comments","depth":2,"text":"Why Choose Comments?"}]}},"meta":{},"__metadata":{},"path":"/getting-started/introduction","stem":"1.getting-started/1.introduction","extension":"md"}


id: docs/2.essentials/2.authorization.md
checksum: b964108384fc5af0e0ab154106f22678
__hash__: U7IH7CzP05_KuZNiI2rs5YrKmqT-GdoyQpKGXJXY2Z4
value:
{"id":"docs/2.essentials/2.authorization.md","title":"Authorization","description":"Control who can create, edit, delete, and reply to comments.","navigation":{"icon":"i-lucide-shield"},"seo":{"description":"Configure comment authorization policies.","title":"Authorization"},"body":{"type":"minimark","value":[["h2",{"id":"default-policy"},"Default Policy"],["p",{},"The built-in ",["code",{},"CommentPolicy"]," provides sensible defaults:"],["table",{},["thead",{},["tr",{},["th",{},"Method"],["th",{},"Default"],["th",{},"Description"]]],["tbody",{},["tr",{},["td",{},["code",{},"viewAny()"]],["td",{},["code",{},"true"]],["td",{},"Everyone can view comments"]],["tr",{},["td",{},["code",{},"create()"]],["td",{},["code",{},"true"]],["td",{},"Everyone can create comments"]],["tr",{},["td",{},["code",{},"update()"]],["td",{},"Owner only"],["td",{},"Only the comment author can edit"]],["tr",{},["td",{},["code",{},"delete()"]],["td",{},"Owner only"],["td",{},"Only the comment author can delete"]],["tr",{},["td",{},["code",{},"reply()"]],["td",{},"Depth check"],["td",{},"Can reply if ",["code",{},"max_depth"]," not exceeded"]]]],["h2",{"id":"custom-policy"},"Custom Policy"],["p",{},"Create your own policy to customize authorization:"],["pre",{"className":"language-php shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","code":"namespace App\\Policies;\n\nuse Relaticle\\Comments\\Comment;\nuse Relaticle\\Comments\\Contracts\\Commenter;\n\nclass CustomCommentPolicy\n{\n    public function viewAny(Commenter $user): bool\n    {\n        return true;\n    }\n\n    public function create(Commenter $user): bool\n    {\n        return true;\n    }\n\n    public function update(Commenter $user, Comment $comment): bool\n    {\n        return $comment->user_id === $user->getKey()\n            && $comment->user_type === $user->getMorphClass();\n    }\n\n    public function delete(Commenter $user, Comment $comment): bool\n    {\n        return $comment->user_id === $user->getKey()\n            || $user->hasRole('admin');\n    }\n\n    public function reply(Commenter $user, Comment $comment): bool\n    {\n        return $comment->canReply();\n    }\n}\n","language":"php","meta":"","style":""},["code",{"__ignoreMap":""},["span",{"class":"line","line":1},["span",{"class":"sbssI"},"namespace"],["span",{"class":"sBMFI"}," App"],["span",{"class":"sMK4o"},"\\"],["span",{"class":"sBMFI"},"Policies"],["span",{"class":"sMK4o"},";\n"]],["span",{"class":"line","line":2},["span",{"emptyLinePlaceholder":true},"\n"]],["span",{"class":"line","line":3},["span",{"class":"sbssI"},"use"],["span",{"class":"sTEyZ"}," Relaticle"],["span",{"class":"sMK4o"},"\\"],["span",{"class":"sTEyZ"},"Comments"],["span",{"class":"sMK4o"},"\\"],["span",{"class":"sTEyZ"},"Comment"],["span",{"class":"sMK4o"},";\n"]],["span",{"class":"line","line":4},["span",{"class":"sbssI"},"use"],["span",{"class":"sTEyZ"}," Relaticle"],["span",{"class":"sMK4o"},"\\"],["span",{"class":"sTEyZ"},"Comments"],["span",{"class":"sMK4o"},"\\"],["span",{"class":"sTEyZ"},"Contracts"],["span",{"class":"sMK4o"},"\\"],["span",{"class":"sTEyZ"},"Commenter"],["span",{"class":"sMK4o"},";\n"]],["span",{"class":"line","line":5},["span",{"emptyLinePlaceholder":true},"\n"]],["span",{"class":"line","line":6},["span",{"class":"spNyl"},"class"],["span",{"class":"sBMFI"}," CustomCommentPolicy\n"]],["span",{"class":"line","line":7},["span",{"class":"sMK4o"},"{\n"]],["span",{"class":"line","line":8},["span",{"class":"spNyl"},"    public"],["span",{"class":"spNyl"}," function"],["span",{"class":"s2Zo4"}," viewAny"],["span",{"class":"sMK4o"},"("],["span",{"class":"sBMFI"},"Commenter"],["span",{"class":"sMK4o"}," $"],["span",{"class":"sTEyZ"},"user"],["span",{"class":"sMK4o"},"):"],["span",{"class":"sbssI"}," bool\n"]],["span",{"class":"line","line":9},["span",{"class":"sMK4o"},"    {\n"]],["span",{"class":"line","line":10},["span",{"class":"s7zQu"},"        return"],["span",{"class":"sMK4o"}," true;\n"]],["span",{"class":"line","line":11},["span",{"class":"sMK4o"},"    }\n"]],["span",{"class":"line","line":12},["span",{"emptyLinePlaceholder":true},"\n"]],["span",{"class":"line","line":13},["span",{"class":"spNyl"},"    public"],["span",{"class":"spNyl"}," function"],["span",{"class":"s2Zo4"}," create"],["span",{"class":"sMK4o"},"("],["span",{"class":"sBMFI"},"Commenter"],["span",{"class":"sMK4o"}," $"],["span",{"class":"sTEyZ"},"user"],["span",{"class":"sMK4o"},"):"],["span",{"class":"sbssI"}," bool\n"]],["span",{"class":"line","line":14},["span",{"class":"sMK4o"},"    {\n"]],["span",{"class":"line","line":15},["span",{"class":"s7zQu"},"        return"],["span",{"class":"sMK4o"}," true;\n"]],["span",{"class":"line","line":16},["span",{"class":"sMK4o"},"    }\n"]],["span",{"class":"line","line":17},["span",{"emptyLinePlaceholder":true},"\n"]],["span",{"class":"line","line":18},["span",{"class":"spNyl"},"    public"],["span",{"class":"spNyl"}," function"],["span",{"class":"s2Zo4"}," update"],["span",{"class":"sMK4o"},"("],["span",{"class":"sBMFI"},"Commenter"],["span",{"class":"sMK4o"}," $"],["span",{"class":"sTEyZ"},"user"],["span",{"class":"sMK4o"},","],["span",{"class":"sBMFI"}," Comment"],["span",{"class":"sMK4o"}," $"],["span",{"class":"sTEyZ"},"comment"],["span",{"class":"sMK4o"},"):"],["span",{"class":"sbssI"}," bool\n"]],["span",{"class":"line","line":19},["span",{"class":"sMK4o"},"    {\n"]],["span",{"class":"line","line":20},["span",{"class":"s7zQu"},"        return"],["span",{"class":"sMK4o"}," $"],["span",{"class":"sTEyZ"},"comment"],["span",{"class":"sMK4o"},"->"],["span",{"class":"sTEyZ"},"user_id "],["span",{"class":"sMK4o"},"==="],["span",{"class":"sMK4o"}," $"],["span",{"class":"sTEyZ"},"user"],["span",{"class":"sMK4o"},"->"],["span",{"class":"s2Zo4"},"getKey"],["span",{"class":"sMK4o"},"()\n"]],["span",{"class":"line","line":21},["span",{"class":"sMK4o"},"            &&"],["span",{"class":"sMK4o"}," $"],["span",{"class":"sTEyZ"},"comment"],["span",{"class":"sMK4o"},"->"],["span",{"class":"sTEyZ"},"user_type "],["span",{"class":"sMK4o"},"==="],["span",{"class":"sMK4o"}," $"],["span",{"class":"sTEyZ"},"user"],["span",{"class":"sMK4o"},"->"],["span",{"class":"s2Zo4"},"getMorphClass"],["span",{"class":"sMK4o"},"();\n"]],["span",{"class":"line","line":22},["span",{"class":"sMK4o"},"    }\n"]],["span",{"class":"line","line":23},["span",{"emptyLinePlaceholder":true},"\n"]],["span",{"class":"line","line":24},["span",{"class":"spNyl"},"    public"],["span",{"class":"spNyl"}," function"],["span",{"class":"s2Zo4"}," delete"],["span",{"class":"sMK4o"},"("],["span",{"class":"sBMFI"},"Commenter"],["span",{"class":"sMK4o"}," $"],["span",{"class":"sTEyZ"},"user"],["span",{"class":"sMK4o"},","],["span",{"class":"sBMFI"}," Comment"],["span",{"class":"sMK4o"}," $"],["span",{"class":"sTEyZ"},"comment"],["span",{"class":"sMK4o"},"):"],["span",{"class":"sbssI"}," bool\n"]],["span",{"class":"line","line":25},["span",{"class":"sMK4o"},"    {\n"]],["span",{"class":"line","line":26},["span",{"class":"s7zQu"},"        return"],["span",{"class":"sMK4o"}," $"],["span",{"class":"sTEyZ"},"comment"],["span",{"class":"sMK4o"},"->"],["span",{"class":"sTEyZ"},"user_id "],["span",{"class":"sMK4o"},"==="],["span",{"class":"sMK4o"}," $"],["span",{"class":"sTEyZ"},"user"],["span",{"class":"sMK4o"},"->"],["span",{"class":"s2Zo4"},"getKey"],["span",{"class":"sMK4o"},"()\n"]],["span",{"class":"line","line":27},["span",{"class":"sMK4o"},"            ||"],["span",{"class":"sMK4o"}," $"],["span",{"class":"sTEyZ"},"user"],["span",{"class":"sMK4o"},"->"],["span",{"class":"s2Zo4"},"hasRole"],["span",{"class":"sMK4o"},"("],["span",{"class":"sMK4o"},"'"],["span",{"class":"sfazB"},"admin"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"},");\n"]],["span",{"class":"line","line":28},["span",{"class":"sMK4o"},"    }\n"]],["span",{"class":"line","line":29},["span",{"emptyLinePlaceholder":true},"\n"]],["span",{"class":"line","line":30},["span",{"class":"spNyl"},"    public"],["span",{"class":"spNyl"}," function"],["span",{"class":"s2Zo4"}," reply"],["span",{"class":"sMK4o"},"("],["span",{"class":"sBMFI"},"Commenter"],["span",{"class":"sMK4o"}," $"],["span",{"class":"sTEyZ"},"user"],["span",{"class":"sMK4o"},","],["span",{"class":"sBMFI"}," Comment"],["span",{"class":"sMK4o"}," $"],["span",{"class":"sTEyZ"},"comment"],["span",{"class":"sMK4o"},"):"],["span",{"class":"sbssI"}," bool\n"]],["span",{"class":"line","line":31},["span",{"class":"sMK4o"},"    {\n"]],["span",{"class":"line","line":32},["span",{"class":"s7zQu"},"        return"],["span",{"class":"sMK4o"}," $"],["span",{"class":"sTEyZ"},"comment"],["span",{"class":"sMK4o"},"->"],["span",{"class":"s2Zo4"},"canReply"],["span",{"class":"sMK4o"},"();\n"]],["span",{"class":"line","line":33},["span",{"class":"sMK4o"},"    }\n"]],["span",{"class":"line","line":34},["span",{"class":"sMK4o"},"}\n"]]]],["p",{},"Register it in your config:"],["pre",{"className":"language-php shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","code":"// config/comments.php\n'policy' => App\\Policies\\CustomCommentPolicy::class,\n","language":"php","meta":"","style":""},["code",{"__ignoreMap":""},["span",{"class":"line","line":1},["span",{"class":"sHwdD"},"// config/comments.php\n"]],["span",{"class":"line","line":2},["span",{"class":"sMK4o"},"'"],["span",{"class":"sfazB"},"policy"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sTEyZ"}," App"],["span",{"class":"sMK4o"},"\\"],["span",{"class":"sTEyZ"},"Policies"],["span",{"class":"sMK4o"},"\\"],["span",{"class":"sBMFI"},"CustomCommentPolicy"],["span",{"class":"sMK4o"},"::"],["span",{"class":"sbssI"},"class"],["span",{"class":"sMK4o"},",\n"]]]],["h2",{"id":"how-authorization-works"},"How Authorization Works"],["p",{},"The Livewire components check the policy before rendering action buttons. Edit and delete buttons only appear for authorized users. Reply buttons are hidden when the thread has reached the configured ",["code",{},"max_depth"],"."],["p",{},"The policy is registered automatically by the service provider using Laravel's Gate system."],["style",{},"html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}"]],"toc":{"title":"","searchDepth":2,"depth":2,"links":[{"id":"default-policy","depth":2,"text":"Default Policy"},{"id":"custom-policy","depth":2,"text":"Custom Policy"},{"id":"how-authorization-works","depth":2,"text":"How Authorization Works"}]}},"meta":{},"__metadata":{},"path":"/essentials/authorization","stem":"2.essentials/2.authorization","extension":"md"}


id: docs/4.community/.navigation.yml
checksum: 8eee19a5a32dcb306adcb883c3dca5a3
__hash__: dyRm8BCkypubEcyGgI9bPAPuPxb2RISFWPn-OO3X1w0
value:
{"id":"docs/4.community/.navigation.yml","title":"Community","meta":{},"__metadata":{},"seo":{"title":"Community"},"path":"/community/.navigation","stem":"4.community/.navigation","extension":"yml"}


id: docs/4.community/2.license.md
checksum: 359d051d8a3a94ad82935e695ee6aa78
__hash__: py1KFWzCanKPBth28SMwMJd3lS4QIdem-2xSrF5gKmI
value:
{"id":"docs/4.community/2.license.md","title":"License","description":"MIT License terms and what it means for you","navigation":{"icon":"i-lucide-scale"},"body":{"type":"minimark","value":[["h2",{"id":"mit-license"},"MIT License"],["pre",{"className":["language-text"],"code":"Copyright (c) Relaticle\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","language":"text"},["code",{"__ignoreMap":""},"Copyright (c) Relaticle\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n"]],["h2",{"id":"what-this-means"},"What This Means"],["p",{},"You ",["strong",{},"can"]," use Comments in commercial projects.\nYou ",["strong",{},"can"]," modify and distribute it.\nYou ",["strong",{},"can"]," use it in closed source projects.\nYou ",["strong",{},"can"]," sell applications that include it."],["p",{},"Just include the license notice in your copy."]],"toc":{"title":"","searchDepth":2,"depth":2,"links":[{"id":"mit-license","depth":2,"text":"MIT License"},{"id":"what-this-means","depth":2,"text":"What This Means"}]}},"meta":{},"__metadata":{},"seo":{"title":"License","description":"MIT License terms and what it means for you"},"path":"/community/license","stem":"4.community/2.license","extension":"md"}


id: docs/2.essentials/.navigation.yml
checksum: 5c8ca94befb0be4b63dbfe01e37837f9
__hash__: oRDRyCgCXWc9QtV1fbmW-wBsAQv68r5VSba4EgRU_B4
value:
{"id":"docs/2.essentials/.navigation.yml","title":"Essentials","meta":{},"__metadata":{},"seo":{"title":"Essentials"},"path":"/essentials/.navigation","stem":"2.essentials/.navigation","extension":"yml"}


id: docs/2.essentials/6.notifications.md
checksum: 184f389f7e836423c8f19cfeeb93c984
__hash__: iXydWHUOM8vcnL1r0_4JiKCzAd5xgVuNFeLYOu-82SE
value:
{"id":"docs/2.essentials/6.notifications.md","title":"Notifications","description":"Comment notifications, subscriptions, and real-time updates.","navigation":{"icon":"i-lucide-bell"},"seo":{"description":"Configure comment notifications, subscriptions, broadcasting, and polling.","title":"Notifications"},"body":{"type":"minimark","value":[["h2",{"id":"notification-types"},"Notification Types"],["p",{},"Two notification classes are included:"],["h3",{"id":"commentrepliednotification"},"CommentRepliedNotification"],["p",{},"Sent to all thread subscribers when a new comment or reply is posted. The comment author is excluded from receiving their own notification."],["h3",{"id":"usermentionednotification"},"UserMentionedNotification"],["p",{},"Sent to a user when they are @mentioned in a comment. Self-mentions are ignored."],["h2",{"id":"channels"},"Channels"],["pre",{"className":"language-php shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","code":"// config/comments.php\n'notifications' => [\n    'channels' => ['database'],\n    'enabled' => true,\n],\n","language":"php","meta":"","style":""},["code",{"__ignoreMap":""},["span",{"class":"line","line":1},["span",{"class":"sHwdD"},"// config/comments.php\n"]],["span",{"class":"line","line":2},["span",{"class":"sMK4o"},"'"],["span",{"class":"sfazB"},"notifications"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," [\n"]],["span",{"class":"line","line":3},["span",{"class":"sMK4o"},"    '"],["span",{"class":"sfazB"},"channels"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," ["],["span",{"class":"sMK4o"},"'"],["span",{"class":"sfazB"},"database"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"},"],\n"]],["span",{"class":"line","line":4},["span",{"class":"sMK4o"},"    '"],["span",{"class":"sfazB"},"enabled"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," true,\n"]],["span",{"class":"line","line":5},["span",{"class":"sMK4o"},"],\n"]]]],["p",{},"Available channels: ",["code",{},"'database'"]," and ",["code",{},"'mail'"],". Add both to send email notifications alongside database notifications:"],["pre",{"className":"language-php shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","code":"'notifications' => [\n    'channels' => ['database', 'mail'],\n    'enabled' => true,\n],\n","language":"php","meta":"","style":""},["code",{"__ignoreMap":""},["span",{"class":"line","line":1},["span",{"class":"sMK4o"},"'"],["span",{"class":"sfazB"},"notifications"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," [\n"]],["span",{"class":"line","line":2},["span",{"class":"sMK4o"},"    '"],["span",{"class":"sfazB"},"channels"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," ["],["span",{"class":"sMK4o"},"'"],["span",{"class":"sfazB"},"database"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"},","],["span",{"class":"sMK4o"}," '"],["span",{"class":"sfazB"},"mail"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"},"],\n"]],["span",{"class":"line","line":3},["span",{"class":"sMK4o"},"    '"],["span",{"class":"sfazB"},"enabled"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," true,\n"]],["span",{"class":"line","line":4},["span",{"class":"sMK4o"},"],\n"]]]],["h2",{"id":"subscriptions"},"Subscriptions"],["p",{},"Users can subscribe to comment threads on any commentable model. Subscribers receive notifications when new comments are posted."],["h3",{"id":"auto-subscribe"},"Auto-Subscribe"],["pre",{"className":"language-php shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","code":"'subscriptions' => [\n    'auto_subscribe' => true,\n],\n","language":"php","meta":"","style":""},["code",{"__ignoreMap":""},["span",{"class":"line","line":1},["span",{"class":"sMK4o"},"'"],["span",{"class":"sfazB"},"subscriptions"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," [\n"]],["span",{"class":"line","line":2},["span",{"class":"sMK4o"},"    '"],["span",{"class":"sfazB"},"auto_subscribe"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," true,\n"]],["span",{"class":"line","line":3},["span",{"class":"sMK4o"},"],\n"]]]],["p",{},"When enabled:"],["ul",{},["li",{},"Users are auto-subscribed when they post a comment"],["li",{},"Users are auto-subscribed when they are @mentioned"]],["h3",{"id":"manual-subscription"},"Manual Subscription"],["p",{},"Users can toggle their subscription using the subscribe/unsubscribe button in the comments UI."],["h3",{"id":"programmatic-access"},"Programmatic Access"],["pre",{"className":"language-php shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","code":"use Relaticle\\Comments\\CommentSubscription;\n\n// Check subscription status\nCommentSubscription::isSubscribed($commentable, $user);\n\n// Subscribe/unsubscribe\nCommentSubscription::subscribe($commentable, $user);\nCommentSubscription::unsubscribe($commentable, $user);\n\n// Get all subscribers for a commentable\n$subscribers = CommentSubscription::subscribersFor($commentable);\n","language":"php","meta":"","style":""},["code",{"__ignoreMap":""},["span",{"class":"line","line":1},["span",{"class":"sbssI"},"use"],["span",{"class":"sTEyZ"}," Relaticle"],["span",{"class":"sMK4o"},"\\"],["span",{"class":"sTEyZ"},"Comments"],["span",{"class":"sMK4o"},"\\"],["span",{"class":"sTEyZ"},"CommentSubscription"],["span",{"class":"sMK4o"},";\n"]],["span",{"class":"line","line":2},["span",{"emptyLinePlaceholder":true},"\n"]],["span",{"class":"line","line":3},["span",{"class":"sHwdD"},"// Check subscription status\n"]],["span",{"class":"line","line":4},["span",{"class":"sBMFI"},"CommentSubscription"],["span",{"class":"sMK4o"},"::"],["span",{"class":"s2Zo4"},"isSubscribed"],["span",{"class":"sMK4o"},"($"],["span",{"class":"sTEyZ"},"commentable"],["span",{"class":"sMK4o"},","],["span",{"class":"sMK4o"}," $"],["span",{"class":"sTEyZ"},"user"],["span",{"class":"sMK4o"},");\n"]],["span",{"class":"line","line":5},["span",{"emptyLinePlaceholder":true},"\n"]],["span",{"class":"line","line":6},["span",{"class":"sHwdD"},"// Subscribe/unsubscribe\n"]],["span",{"class":"line","line":7},["span",{"class":"sBMFI"},"CommentSubscription"],["span",{"class":"sMK4o"},"::"],["span",{"class":"s2Zo4"},"subscribe"],["span",{"class":"sMK4o"},"($"],["span",{"class":"sTEyZ"},"commentable"],["span",{"class":"sMK4o"},","],["span",{"class":"sMK4o"}," $"],["span",{"class":"sTEyZ"},"user"],["span",{"class":"sMK4o"},");\n"]],["span",{"class":"line","line":8},["span",{"class":"sBMFI"},"CommentSubscription"],["span",{"class":"sMK4o"},"::"],["span",{"class":"s2Zo4"},"unsubscribe"],["span",{"class":"sMK4o"},"($"],["span",{"class":"sTEyZ"},"commentable"],["span",{"class":"sMK4o"},","],["span",{"class":"sMK4o"}," $"],["span",{"class":"sTEyZ"},"user"],["span",{"class":"sMK4o"},");\n"]],["span",{"class":"line","line":9},["span",{"emptyLinePlaceholder":true},"\n"]],["span",{"class":"line","line":10},["span",{"class":"sHwdD"},"// Get all subscribers for a commentable\n"]],["span",{"class":"line","line":11},["span",{"class":"sMK4o"},"$"],["span",{"class":"sTEyZ"},"subscribers "],["span",{"class":"sMK4o"},"="],["span",{"class":"sBMFI"}," CommentSubscription"],["span",{"class":"sMK4o"},"::"],["span",{"class":"s2Zo4"},"subscribersFor"],["span",{"class":"sMK4o"},"($"],["span",{"class":"sTEyZ"},"commentable"],["span",{"class":"sMK4o"},");\n"]]]],["h2",{"id":"events"},"Events"],["table",{},["thead",{},["tr",{},["th",{},"Event"],["th",{},"Trigger"],["th",{},"Broadcasts"]]],["tbody",{},["tr",{},["td",{},["code",{},"CommentCreated"]],["td",{},"New comment or reply"],["td",{},"Yes"]],["tr",{},["td",{},["code",{},"CommentUpdated"]],["td",{},"Comment edited"],["td",{},"Yes"]],["tr",{},["td",{},["code",{},"CommentDeleted"]],["td",{},"Comment soft-deleted"],["td",{},"Yes"]],["tr",{},["td",{},["code",{},"CommentReacted"]],["td",{},"Reaction added/removed"],["td",{},"Yes"]],["tr",{},["td",{},["code",{},"UserMentioned"]],["td",{},"User @mentioned"],["td",{},"No"]]]],["h2",{"id":"real-time-updates"},"Real-time Updates"],["h3",{"id":"broadcasting"},"Broadcasting"],["p",{},"Enable broadcasting for instant updates across browser sessions:"],["pre",{"className":"language-php shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","code":"// config/comments.php\n'broadcasting' => [\n    'enabled' => true,\n    'channel_prefix' => 'comments',\n],\n","language":"php","meta":"","style":""},["code",{"__ignoreMap":""},["span",{"class":"line","line":1},["span",{"class":"sHwdD"},"// config/comments.php\n"]],["span",{"class":"line","line":2},["span",{"class":"sMK4o"},"'"],["span",{"class":"sfazB"},"broadcasting"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," [\n"]],["span",{"class":"line","line":3},["span",{"class":"sMK4o"},"    '"],["span",{"class":"sfazB"},"enabled"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," true,\n"]],["span",{"class":"line","line":4},["span",{"class":"sMK4o"},"    '"],["span",{"class":"sfazB"},"channel_prefix"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," '"],["span",{"class":"sfazB"},"comments"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"},",\n"]],["span",{"class":"line","line":5},["span",{"class":"sMK4o"},"],\n"]]]],["p",{},"Events are broadcast on private channels: ",["code",{},"{prefix}.{commentable_type}.{commentable_id}"]],["p",{},"This requires Laravel Echo and a broadcasting driver (Pusher, Ably, etc.) configured in your application."],["h3",{"id":"polling-fallback"},"Polling Fallback"],["p",{},"When broadcasting is disabled, the Livewire component polls for updates:"],["pre",{"className":"language-php shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","code":"'polling' => [\n    'interval' => '10s',\n],\n","language":"php","meta":"","style":""},["code",{"__ignoreMap":""},["span",{"class":"line","line":1},["span",{"class":"sMK4o"},"'"],["span",{"class":"sfazB"},"polling"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," [\n"]],["span",{"class":"line","line":2},["span",{"class":"sMK4o"},"    '"],["span",{"class":"sfazB"},"interval"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," '"],["span",{"class":"sfazB"},"10s"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"},",\n"]],["span",{"class":"line","line":3},["span",{"class":"sMK4o"},"],\n"]]]],["p",{},"Set to ",["code",{},"null"]," to disable polling entirely."],["h2",{"id":"disabling-notifications"},"Disabling Notifications"],["pre",{"className":"language-php shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","code":"'notifications' => [\n    'enabled' => false,\n],\n","language":"php","meta":"","style":""},["code",{"__ignoreMap":""},["span",{"class":"line","line":1},["span",{"class":"sMK4o"},"'"],["span",{"class":"sfazB"},"notifications"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," [\n"]],["span",{"class":"line","line":2},["span",{"class":"sMK4o"},"    '"],["span",{"class":"sfazB"},"enabled"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," false,\n"]],["span",{"class":"line","line":3},["span",{"class":"sMK4o"},"],\n"]]]],["p",{},"This disables all notification dispatching. Subscriptions and events still work, but no notifications are sent."],["style",{},"html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}"]],"toc":{"title":"","searchDepth":2,"depth":2,"links":[{"id":"notification-types","depth":2,"text":"Notification Types","children":[{"id":"commentrepliednotification","depth":3,"text":"CommentRepliedNotification"},{"id":"usermentionednotification","depth":3,"text":"UserMentionedNotification"}]},{"id":"channels","depth":2,"text":"Channels"},{"id":"subscriptions","depth":2,"text":"Subscriptions","children":[{"id":"auto-subscribe","depth":3,"text":"Auto-Subscribe"},{"id":"manual-subscription","depth":3,"text":"Manual Subscription"},{"id":"programmatic-access","depth":3,"text":"Programmatic Access"}]},{"id":"events","depth":2,"text":"Events"},{"id":"real-time-updates","depth":2,"text":"Real-time Updates","children":[{"id":"broadcasting","depth":3,"text":"Broadcasting"},{"id":"polling-fallback","depth":3,"text":"Polling Fallback"}]},{"id":"disabling-notifications","depth":2,"text":"Disabling Notifications"}]}},"meta":{},"__metadata":{},"path":"/essentials/notifications","stem":"2.essentials/6.notifications","extension":"md"}


id: docs/2.essentials/3.mentions.md
checksum: 9a86b176ecf41ce2cfba2e63c8eb6f42
__hash__: oMBi6CokKy_YmhKjDEJ2fVKoH-rkxLlosvwDSESqi9g
value:
{"id":"docs/2.essentials/3.mentions.md","title":"Mentions","description":"User @mentions with autocomplete and notification support.","navigation":{"icon":"i-lucide-at-sign"},"seo":{"description":"Configure @mention autocomplete and create custom mention resolvers.","title":"Mentions"},"body":{"type":"minimark","value":[["h2",{"id":"how-mentions-work"},"How Mentions Work"],["p",{},"Type ",["code",{},"@"]," in the comment editor to trigger user autocomplete. Select a user to insert a mention. When the comment is saved, the ",["code",{},"MentionParser"]," extracts mentions and:"],["ol",{},["li",{},"Syncs mention records in the ",["code",{},"comment_mentions"]," table"],["li",{},"Dispatches a ",["code",{},"UserMentioned"]," event for each newly mentioned user"],["li",{},"The ",["code",{},"SendUserMentionedNotification"]," listener sends notifications"],["li",{},"If auto-subscribe is enabled, mentioned users are subscribed to the thread"]],["h2",{"id":"default-resolver"},"Default Resolver"],["p",{},"The ",["code",{},"DefaultMentionResolver"]," searches the commenter model by name:"],["pre",{"className":"language-php shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","code":"// Searches: User::where('name', 'like', \"{$query}%\")\n// Limited to: config('comments.mentions.max_results') results\n","language":"php","meta":"","style":""},["code",{"__ignoreMap":""},["span",{"class":"line","line":1},["span",{"class":"sHwdD"},"// Searches: User::where('name', 'like', \"{$query}%\")\n"]],["span",{"class":"line","line":2},["span",{"class":"sHwdD"},"// Limited to: config('comments.mentions.max_results') results\n"]]]],["h2",{"id":"custom-mention-resolver"},"Custom Mention Resolver"],["p",{},"Implement the ",["code",{},"MentionResolver"]," interface to customize user search behavior:"],["pre",{"className":"language-php shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","code":"namespace App\\Comments;\n\nuse Illuminate\\Support\\Collection;\nuse Relaticle\\Comments\\Contracts\\MentionResolver;\n\nclass TeamMentionResolver implements MentionResolver\n{\n    public function search(string $query): Collection\n    {\n        return User::query()\n            ->where('team_id', auth()->user()->team_id)\n            ->where('name', 'like', \"{$query}%\")\n            ->limit(config('comments.mentions.max_results'))\n            ->get();\n    }\n\n    public function resolveByNames(array $names): Collection\n    {\n        return User::query()\n            ->where('team_id', auth()->user()->team_id)\n            ->whereIn('name', $names)\n            ->get();\n    }\n}\n","language":"php","meta":"","style":""},["code",{"__ignoreMap":""},["span",{"class":"line","line":1},["span",{"class":"sbssI"},"namespace"],["span",{"class":"sBMFI"}," App"],["span",{"class":"sMK4o"},"\\"],["span",{"class":"sBMFI"},"Comments"],["span",{"class":"sMK4o"},";\n"]],["span",{"class":"line","line":2},["span",{"emptyLinePlaceholder":true},"\n"]],["span",{"class":"line","line":3},["span",{"class":"sbssI"},"use"],["span",{"class":"sTEyZ"}," Illuminate"],["span",{"class":"sMK4o"},"\\"],["span",{"class":"sTEyZ"},"Support"],["span",{"class":"sMK4o"},"\\"],["span",{"class":"sTEyZ"},"Collection"],["span",{"class":"sMK4o"},";\n"]],["span",{"class":"line","line":4},["span",{"class":"sbssI"},"use"],["span",{"class":"sTEyZ"}," Relaticle"],["span",{"class":"sMK4o"},"\\"],["span",{"class":"sTEyZ"},"Comments"],["span",{"class":"sMK4o"},"\\"],["span",{"class":"sTEyZ"},"Contracts"],["span",{"class":"sMK4o"},"\\"],["span",{"class":"sTEyZ"},"MentionResolver"],["span",{"class":"sMK4o"},";\n"]],["span",{"class":"line","line":5},["span",{"emptyLinePlaceholder":true},"\n"]],["span",{"class":"line","line":6},["span",{"class":"spNyl"},"class"],["span",{"class":"sBMFI"}," TeamMentionResolver"],["span",{"class":"spNyl"}," implements"],["span",{"class":"sBMFI"}," MentionResolver\n"]],["span",{"class":"line","line":7},["span",{"class":"sMK4o"},"{\n"]],["span",{"class":"line","line":8},["span",{"class":"spNyl"},"    public"],["span",{"class":"spNyl"}," function"],["span",{"class":"s2Zo4"}," search"],["span",{"class":"sMK4o"},"("],["span",{"class":"sbssI"},"string"],["span",{"class":"sMK4o"}," $"],["span",{"class":"sTEyZ"},"query"],["span",{"class":"sMK4o"},"):"],["span",{"class":"sBMFI"}," Collection\n"]],["span",{"class":"line","line":9},["span",{"class":"sMK4o"},"    {\n"]],["span",{"class":"line","line":10},["span",{"class":"s7zQu"},"        return"],["span",{"class":"sBMFI"}," User"],["span",{"class":"sMK4o"},"::"],["span",{"class":"s2Zo4"},"query"],["span",{"class":"sMK4o"},"()\n"]],["span",{"class":"line","line":11},["span",{"class":"sMK4o"},"            ->"],["span",{"class":"s2Zo4"},"where"],["span",{"class":"sMK4o"},"("],["span",{"class":"sMK4o"},"'"],["span",{"class":"sfazB"},"team_id"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"},","],["span",{"class":"s2Zo4"}," auth"],["span",{"class":"sMK4o"},"()->"],["span",{"class":"s2Zo4"},"user"],["span",{"class":"sMK4o"},"()->"],["span",{"class":"sTEyZ"},"team_id"],["span",{"class":"sMK4o"},")\n"]],["span",{"class":"line","line":12},["span",{"class":"sMK4o"},"            ->"],["span",{"class":"s2Zo4"},"where"],["span",{"class":"sMK4o"},"("],["span",{"class":"sMK4o"},"'"],["span",{"class":"sfazB"},"name"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"},","],["span",{"class":"sMK4o"}," '"],["span",{"class":"sfazB"},"like"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"},","],["span",{"class":"sMK4o"}," \"{$"],["span",{"class":"sTEyZ"},"query"],["span",{"class":"sMK4o"},"}"],["span",{"class":"sfazB"},"%"],["span",{"class":"sMK4o"},"\""],["span",{"class":"sMK4o"},")\n"]],["span",{"class":"line","line":13},["span",{"class":"sMK4o"},"            ->"],["span",{"class":"s2Zo4"},"limit"],["span",{"class":"sMK4o"},"("],["span",{"class":"s2Zo4"},"config"],["span",{"class":"sMK4o"},"("],["span",{"class":"sMK4o"},"'"],["span",{"class":"sfazB"},"comments.mentions.max_results"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"},"))\n"]],["span",{"class":"line","line":14},["span",{"class":"sMK4o"},"            ->"],["span",{"class":"s2Zo4"},"get"],["span",{"class":"sMK4o"},"();\n"]],["span",{"class":"line","line":15},["span",{"class":"sMK4o"},"    }\n"]],["span",{"class":"line","line":16},["span",{"emptyLinePlaceholder":true},"\n"]],["span",{"class":"line","line":17},["span",{"class":"spNyl"},"    public"],["span",{"class":"spNyl"}," function"],["span",{"class":"s2Zo4"}," resolveByNames"],["span",{"class":"sMK4o"},"("],["span",{"class":"sbssI"},"array"],["span",{"class":"sMK4o"}," $"],["span",{"class":"sTEyZ"},"names"],["span",{"class":"sMK4o"},"):"],["span",{"class":"sBMFI"}," Collection\n"]],["span",{"class":"line","line":18},["span",{"class":"sMK4o"},"    {\n"]],["span",{"class":"line","line":19},["span",{"class":"s7zQu"},"        return"],["span",{"class":"sBMFI"}," User"],["span",{"class":"sMK4o"},"::"],["span",{"class":"s2Zo4"},"query"],["span",{"class":"sMK4o"},"()\n"]],["span",{"class":"line","line":20},["span",{"class":"sMK4o"},"            ->"],["span",{"class":"s2Zo4"},"where"],["span",{"class":"sMK4o"},"("],["span",{"class":"sMK4o"},"'"],["span",{"class":"sfazB"},"team_id"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"},","],["span",{"class":"s2Zo4"}," auth"],["span",{"class":"sMK4o"},"()->"],["span",{"class":"s2Zo4"},"user"],["span",{"class":"sMK4o"},"()->"],["span",{"class":"sTEyZ"},"team_id"],["span",{"class":"sMK4o"},")\n"]],["span",{"class":"line","line":21},["span",{"class":"sMK4o"},"            ->"],["span",{"class":"s2Zo4"},"whereIn"],["span",{"class":"sMK4o"},"("],["span",{"class":"sMK4o"},"'"],["span",{"class":"sfazB"},"name"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"},","],["span",{"class":"sMK4o"}," $"],["span",{"class":"sTEyZ"},"names"],["span",{"class":"sMK4o"},")\n"]],["span",{"class":"line","line":22},["span",{"class":"sMK4o"},"            ->"],["span",{"class":"s2Zo4"},"get"],["span",{"class":"sMK4o"},"();\n"]],["span",{"class":"line","line":23},["span",{"class":"sMK4o"},"    }\n"]],["span",{"class":"line","line":24},["span",{"class":"sMK4o"},"}\n"]]]],["p",{},"Register it in your config:"],["pre",{"className":"language-php shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","code":"// config/comments.php\n'mentions' => [\n    'resolver' => App\\Comments\\TeamMentionResolver::class,\n    'max_results' => 5,\n],\n","language":"php","meta":"","style":""},["code",{"__ignoreMap":""},["span",{"class":"line","line":1},["span",{"class":"sHwdD"},"// config/comments.php\n"]],["span",{"class":"line","line":2},["span",{"class":"sMK4o"},"'"],["span",{"class":"sfazB"},"mentions"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," [\n"]],["span",{"class":"line","line":3},["span",{"class":"sMK4o"},"    '"],["span",{"class":"sfazB"},"resolver"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sTEyZ"}," App"],["span",{"class":"sMK4o"},"\\"],["span",{"class":"sTEyZ"},"Comments"],["span",{"class":"sMK4o"},"\\"],["span",{"class":"sBMFI"},"TeamMentionResolver"],["span",{"class":"sMK4o"},"::"],["span",{"class":"sbssI"},"class"],["span",{"class":"sMK4o"},",\n"]],["span",{"class":"line","line":4},["span",{"class":"sMK4o"},"    '"],["span",{"class":"sfazB"},"max_results"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sbssI"}," 5"],["span",{"class":"sMK4o"},",\n"]],["span",{"class":"line","line":5},["span",{"class":"sMK4o"},"],\n"]]]],["h2",{"id":"configuration"},"Configuration"],["table",{},["thead",{},["tr",{},["th",{},"Key"],["th",{},"Default"],["th",{},"Description"]]],["tbody",{},["tr",{},["td",{},["code",{},"mentions.resolver"]],["td",{},["code",{},"DefaultMentionResolver::class"]],["td",{},"User search implementation"]],["tr",{},["td",{},["code",{},"mentions.max_results"]],["td",{},["code",{},"5"]],["td",{},"Maximum autocomplete results"]]]],["style",{},"html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}"]],"toc":{"title":"","searchDepth":2,"depth":2,"links":[{"id":"how-mentions-work","depth":2,"text":"How Mentions Work"},{"id":"default-resolver","depth":2,"text":"Default Resolver"},{"id":"custom-mention-resolver","depth":2,"text":"Custom Mention Resolver"},{"id":"configuration","depth":2,"text":"Configuration"}]}},"meta":{},"__metadata":{},"path":"/essentials/mentions","stem":"2.essentials/3.mentions","extension":"md"}


id: docs/2.essentials/1.configuration.md
checksum: 914e7a27c9e83402aef85ac05f5fdb87
__hash__: RyWi74ypchEW2c3v1BQg8nNzXYHWA85VSqrJC5nB0ak
value:
{"id":"docs/2.essentials/1.configuration.md","title":"Configuration","description":"Configure threading, reactions, mentions, attachments, notifications, and more.","navigation":{"icon":"i-lucide-settings"},"seo":{"description":"Complete configuration reference for the Comments package.","title":"Configuration"},"body":{"type":"minimark","value":[["p",{},"Publish the configuration file:"],["pre",{"className":"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","code":"php artisan vendor:publish --tag=comments-config\n","language":"bash","meta":"","style":""},["code",{"__ignoreMap":""},["span",{"class":"line","line":1},["span",{"class":"sBMFI"},"php"],["span",{"class":"sfazB"}," artisan"],["span",{"class":"sfazB"}," vendor:publish"],["span",{"class":"sfazB"}," --tag=comments-config\n"]]]],["p",{},"This creates ",["code",{},"config/comments.php"]," with all available options."],["h2",{"id":"table-name"},"Table Name"],["pre",{"className":"language-php shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","code":"'tables' => [\n    'comments' => 'comments',\n],\n","language":"php","meta":"","style":""},["code",{"__ignoreMap":""},["span",{"class":"line","line":1},["span",{"class":"sMK4o"},"'"],["span",{"class":"sfazB"},"tables"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," [\n"]],["span",{"class":"line","line":2},["span",{"class":"sMK4o"},"    '"],["span",{"class":"sfazB"},"comments"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," '"],["span",{"class":"sfazB"},"comments"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"},",\n"]],["span",{"class":"line","line":3},["span",{"class":"sMK4o"},"],\n"]]]],["p",{},"Change the table name if it conflicts with your application."],["h2",{"id":"models"},"Models"],["pre",{"className":"language-php shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","code":"'models' => [\n    'comment' => \\Relaticle\\Comments\\Comment::class,\n],\n\n'commenter' => [\n    'model' => \\App\\Models\\User::class,\n],\n","language":"php","meta":"","style":""},["code",{"__ignoreMap":""},["span",{"class":"line","line":1},["span",{"class":"sMK4o"},"'"],["span",{"class":"sfazB"},"models"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," [\n"]],["span",{"class":"line","line":2},["span",{"class":"sMK4o"},"    '"],["span",{"class":"sfazB"},"comment"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," \\"],["span",{"class":"sTEyZ"},"Relaticle"],["span",{"class":"sMK4o"},"\\"],["span",{"class":"sTEyZ"},"Comments"],["span",{"class":"sMK4o"},"\\"],["span",{"class":"sBMFI"},"Comment"],["span",{"class":"sMK4o"},"::"],["span",{"class":"sbssI"},"class"],["span",{"class":"sMK4o"},",\n"]],["span",{"class":"line","line":3},["span",{"class":"sMK4o"},"],\n"]],["span",{"class":"line","line":4},["span",{"emptyLinePlaceholder":true},"\n"]],["span",{"class":"line","line":5},["span",{"class":"sMK4o"},"'"],["span",{"class":"sfazB"},"commenter"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," [\n"]],["span",{"class":"line","line":6},["span",{"class":"sMK4o"},"    '"],["span",{"class":"sfazB"},"model"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," \\"],["span",{"class":"sTEyZ"},"App"],["span",{"class":"sMK4o"},"\\"],["span",{"class":"sTEyZ"},"Models"],["span",{"class":"sMK4o"},"\\"],["span",{"class":"sBMFI"},"User"],["span",{"class":"sMK4o"},"::"],["span",{"class":"sbssI"},"class"],["span",{"class":"sMK4o"},",\n"]],["span",{"class":"line","line":7},["span",{"class":"sMK4o"},"],\n"]]]],["p",{},"Override the Comment model to add custom behavior. The commenter model defines which class represents the user who comments."],["h2",{"id":"policy"},"Policy"],["pre",{"className":"language-php shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","code":"'policy' => \\Relaticle\\Comments\\Policies\\CommentPolicy::class,\n","language":"php","meta":"","style":""},["code",{"__ignoreMap":""},["span",{"class":"line","line":1},["span",{"class":"sMK4o"},"'"],["span",{"class":"sfazB"},"policy"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," \\"],["span",{"class":"sTEyZ"},"Relaticle"],["span",{"class":"sMK4o"},"\\"],["span",{"class":"sTEyZ"},"Comments"],["span",{"class":"sMK4o"},"\\"],["span",{"class":"sTEyZ"},"Policies"],["span",{"class":"sMK4o"},"\\"],["span",{"class":"sBMFI"},"CommentPolicy"],["span",{"class":"sMK4o"},"::"],["span",{"class":"sbssI"},"class"],["span",{"class":"sMK4o"},",\n"]]]],["p",{},"See the ",["a",{"href":"/essentials/authorization"},"Authorization"]," page for customization details."],["h2",{"id":"threading"},"Threading"],["pre",{"className":"language-php shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","code":"'threading' => [\n    'max_depth' => 2,\n],\n","language":"php","meta":"","style":""},["code",{"__ignoreMap":""},["span",{"class":"line","line":1},["span",{"class":"sMK4o"},"'"],["span",{"class":"sfazB"},"threading"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," [\n"]],["span",{"class":"line","line":2},["span",{"class":"sMK4o"},"    '"],["span",{"class":"sfazB"},"max_depth"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sbssI"}," 2"],["span",{"class":"sMK4o"},",\n"]],["span",{"class":"line","line":3},["span",{"class":"sMK4o"},"],\n"]]]],["p",{},"Controls how many levels of nested replies are allowed. A depth of ",["code",{},"2"]," means top-level comments and one level of replies. Set to ",["code",{},"1"]," to disable replies entirely."],["h2",{"id":"pagination"},"Pagination"],["pre",{"className":"language-php shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","code":"'pagination' => [\n    'per_page' => 10,\n],\n","language":"php","meta":"","style":""},["code",{"__ignoreMap":""},["span",{"class":"line","line":1},["span",{"class":"sMK4o"},"'"],["span",{"class":"sfazB"},"pagination"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," [\n"]],["span",{"class":"line","line":2},["span",{"class":"sMK4o"},"    '"],["span",{"class":"sfazB"},"per_page"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sbssI"}," 10"],["span",{"class":"sMK4o"},",\n"]],["span",{"class":"line","line":3},["span",{"class":"sMK4o"},"],\n"]]]],["p",{},"Number of comments loaded initially and per \"Load More\" click."],["h2",{"id":"reactions"},"Reactions"],["pre",{"className":"language-php shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","code":"'reactions' => [\n    'emoji_set' => [\n        'thumbs_up' => \"\\u{1F44D}\",\n        'heart' => \"\\u{2764}\\u{FE0F}\",\n        'celebrate' => \"\\u{1F389}\",\n        'laugh' => \"\\u{1F604}\",\n        'thinking' => \"\\u{1F914}\",\n        'sad' => \"\\u{1F622}\",\n    ],\n],\n","language":"php","meta":"","style":""},["code",{"__ignoreMap":""},["span",{"class":"line","line":1},["span",{"class":"sMK4o"},"'"],["span",{"class":"sfazB"},"reactions"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," [\n"]],["span",{"class":"line","line":2},["span",{"class":"sMK4o"},"    '"],["span",{"class":"sfazB"},"emoji_set"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," [\n"]],["span",{"class":"line","line":3},["span",{"class":"sMK4o"},"        '"],["span",{"class":"sfazB"},"thumbs_up"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," \""],["span",{"class":"sTEyZ"},"\\u{1F44D}"],["span",{"class":"sMK4o"},"\""],["span",{"class":"sMK4o"},",\n"]],["span",{"class":"line","line":4},["span",{"class":"sMK4o"},"        '"],["span",{"class":"sfazB"},"heart"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," \""],["span",{"class":"sTEyZ"},"\\u{2764}\\u{FE0F}"],["span",{"class":"sMK4o"},"\""],["span",{"class":"sMK4o"},",\n"]],["span",{"class":"line","line":5},["span",{"class":"sMK4o"},"        '"],["span",{"class":"sfazB"},"celebrate"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," \""],["span",{"class":"sTEyZ"},"\\u{1F389}"],["span",{"class":"sMK4o"},"\""],["span",{"class":"sMK4o"},",\n"]],["span",{"class":"line","line":6},["span",{"class":"sMK4o"},"        '"],["span",{"class":"sfazB"},"laugh"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," \""],["span",{"class":"sTEyZ"},"\\u{1F604}"],["span",{"class":"sMK4o"},"\""],["span",{"class":"sMK4o"},",\n"]],["span",{"class":"line","line":7},["span",{"class":"sMK4o"},"        '"],["span",{"class":"sfazB"},"thinking"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," \""],["span",{"class":"sTEyZ"},"\\u{1F914}"],["span",{"class":"sMK4o"},"\""],["span",{"class":"sMK4o"},",\n"]],["span",{"class":"line","line":8},["span",{"class":"sMK4o"},"        '"],["span",{"class":"sfazB"},"sad"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," \""],["span",{"class":"sTEyZ"},"\\u{1F622}"],["span",{"class":"sMK4o"},"\""],["span",{"class":"sMK4o"},",\n"]],["span",{"class":"line","line":9},["span",{"class":"sMK4o"},"    ],\n"]],["span",{"class":"line","line":10},["span",{"class":"sMK4o"},"],\n"]]]],["p",{},"Customize the available emoji reactions. Keys are used as identifiers in the database, values are the displayed emoji characters."],["h2",{"id":"mentions"},"Mentions"],["pre",{"className":"language-php shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","code":"'mentions' => [\n    'resolver' => \\Relaticle\\Comments\\Mentions\\DefaultMentionResolver::class,\n    'max_results' => 5,\n],\n","language":"php","meta":"","style":""},["code",{"__ignoreMap":""},["span",{"class":"line","line":1},["span",{"class":"sMK4o"},"'"],["span",{"class":"sfazB"},"mentions"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," [\n"]],["span",{"class":"line","line":2},["span",{"class":"sMK4o"},"    '"],["span",{"class":"sfazB"},"resolver"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," \\"],["span",{"class":"sTEyZ"},"Relaticle"],["span",{"class":"sMK4o"},"\\"],["span",{"class":"sTEyZ"},"Comments"],["span",{"class":"sMK4o"},"\\"],["span",{"class":"sTEyZ"},"Mentions"],["span",{"class":"sMK4o"},"\\"],["span",{"class":"sBMFI"},"DefaultMentionResolver"],["span",{"class":"sMK4o"},"::"],["span",{"class":"sbssI"},"class"],["span",{"class":"sMK4o"},",\n"]],["span",{"class":"line","line":3},["span",{"class":"sMK4o"},"    '"],["span",{"class":"sfazB"},"max_results"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sbssI"}," 5"],["span",{"class":"sMK4o"},",\n"]],["span",{"class":"line","line":4},["span",{"class":"sMK4o"},"],\n"]]]],["p",{},"The resolver handles searching for users during @mention autocomplete. See the ",["a",{"href":"/essentials/mentions"},"Mentions"]," page for creating a custom resolver."],["h2",{"id":"editor-toolbar"},"Editor Toolbar"],["pre",{"className":"language-php shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","code":"'editor' => [\n    'toolbar' => [\n        ['bold', 'italic', 'strike', 'link'],\n        ['bulletList', 'orderedList'],\n        ['codeBlock'],\n    ],\n],\n","language":"php","meta":"","style":""},["code",{"__ignoreMap":""},["span",{"class":"line","line":1},["span",{"class":"sMK4o"},"'"],["span",{"class":"sfazB"},"editor"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," [\n"]],["span",{"class":"line","line":2},["span",{"class":"sMK4o"},"    '"],["span",{"class":"sfazB"},"toolbar"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," [\n"]],["span",{"class":"line","line":3},["span",{"class":"sMK4o"},"        ["],["span",{"class":"sMK4o"},"'"],["span",{"class":"sfazB"},"bold"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"},","],["span",{"class":"sMK4o"}," '"],["span",{"class":"sfazB"},"italic"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"},","],["span",{"class":"sMK4o"}," '"],["span",{"class":"sfazB"},"strike"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"},","],["span",{"class":"sMK4o"}," '"],["span",{"class":"sfazB"},"link"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"},"],\n"]],["span",{"class":"line","line":4},["span",{"class":"sMK4o"},"        ["],["span",{"class":"sMK4o"},"'"],["span",{"class":"sfazB"},"bulletList"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"},","],["span",{"class":"sMK4o"}," '"],["span",{"class":"sfazB"},"orderedList"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"},"],\n"]],["span",{"class":"line","line":5},["span",{"class":"sMK4o"},"        ["],["span",{"class":"sMK4o"},"'"],["span",{"class":"sfazB"},"codeBlock"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"},"],\n"]],["span",{"class":"line","line":6},["span",{"class":"sMK4o"},"    ],\n"]],["span",{"class":"line","line":7},["span",{"class":"sMK4o"},"],\n"]]]],["p",{},"Defines which formatting buttons appear in the comment editor. Groups create visual separators in the toolbar."],["h2",{"id":"notifications"},"Notifications"],["pre",{"className":"language-php shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","code":"'notifications' => [\n    'channels' => ['database'],\n    'enabled' => true,\n],\n","language":"php","meta":"","style":""},["code",{"__ignoreMap":""},["span",{"class":"line","line":1},["span",{"class":"sMK4o"},"'"],["span",{"class":"sfazB"},"notifications"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," [\n"]],["span",{"class":"line","line":2},["span",{"class":"sMK4o"},"    '"],["span",{"class":"sfazB"},"channels"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," ["],["span",{"class":"sMK4o"},"'"],["span",{"class":"sfazB"},"database"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"},"],\n"]],["span",{"class":"line","line":3},["span",{"class":"sMK4o"},"    '"],["span",{"class":"sfazB"},"enabled"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," true,\n"]],["span",{"class":"line","line":4},["span",{"class":"sMK4o"},"],\n"]]]],["p",{},"Add ",["code",{},"'mail'"]," to the channels array to send email notifications. Set ",["code",{},"enabled"]," to ",["code",{},"false"]," to disable all notifications."],["h2",{"id":"subscriptions"},"Subscriptions"],["pre",{"className":"language-php shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","code":"'subscriptions' => [\n    'auto_subscribe' => true,\n],\n","language":"php","meta":"","style":""},["code",{"__ignoreMap":""},["span",{"class":"line","line":1},["span",{"class":"sMK4o"},"'"],["span",{"class":"sfazB"},"subscriptions"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," [\n"]],["span",{"class":"line","line":2},["span",{"class":"sMK4o"},"    '"],["span",{"class":"sfazB"},"auto_subscribe"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," true,\n"]],["span",{"class":"line","line":3},["span",{"class":"sMK4o"},"],\n"]]]],["p",{},"When enabled, users are automatically subscribed to a thread when they create a comment or are mentioned. They receive notifications for subsequent replies."],["h2",{"id":"attachments"},"Attachments"],["pre",{"className":"language-php shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","code":"'attachments' => [\n    'enabled' => true,\n    'disk' => 'public',\n    'max_size' => 10240, // KB\n    'allowed_types' => [\n        'image/jpeg',\n        'image/png',\n        'image/gif',\n        'image/webp',\n        'application/pdf',\n        'text/plain',\n        'application/msword',\n        'application/vnd.openxmlformats-officedocument.wordprocessingml.document',\n    ],\n],\n","language":"php","meta":"","style":""},["code",{"__ignoreMap":""},["span",{"class":"line","line":1},["span",{"class":"sMK4o"},"'"],["span",{"class":"sfazB"},"attachments"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," [\n"]],["span",{"class":"line","line":2},["span",{"class":"sMK4o"},"    '"],["span",{"class":"sfazB"},"enabled"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," true,\n"]],["span",{"class":"line","line":3},["span",{"class":"sMK4o"},"    '"],["span",{"class":"sfazB"},"disk"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," '"],["span",{"class":"sfazB"},"public"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"},",\n"]],["span",{"class":"line","line":4},["span",{"class":"sMK4o"},"    '"],["span",{"class":"sfazB"},"max_size"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sbssI"}," 10240"],["span",{"class":"sMK4o"},","],["span",{"class":"sHwdD"}," // KB\n"]],["span",{"class":"line","line":5},["span",{"class":"sMK4o"},"    '"],["span",{"class":"sfazB"},"allowed_types"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," [\n"]],["span",{"class":"line","line":6},["span",{"class":"sMK4o"},"        '"],["span",{"class":"sfazB"},"image/jpeg"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"},",\n"]],["span",{"class":"line","line":7},["span",{"class":"sMK4o"},"        '"],["span",{"class":"sfazB"},"image/png"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"},",\n"]],["span",{"class":"line","line":8},["span",{"class":"sMK4o"},"        '"],["span",{"class":"sfazB"},"image/gif"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"},",\n"]],["span",{"class":"line","line":9},["span",{"class":"sMK4o"},"        '"],["span",{"class":"sfazB"},"image/webp"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"},",\n"]],["span",{"class":"line","line":10},["span",{"class":"sMK4o"},"        '"],["span",{"class":"sfazB"},"application/pdf"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"},",\n"]],["span",{"class":"line","line":11},["span",{"class":"sMK4o"},"        '"],["span",{"class":"sfazB"},"text/plain"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"},",\n"]],["span",{"class":"line","line":12},["span",{"class":"sMK4o"},"        '"],["span",{"class":"sfazB"},"application/msword"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"},",\n"]],["span",{"class":"line","line":13},["span",{"class":"sMK4o"},"        '"],["span",{"class":"sfazB"},"application/vnd.openxmlformats-officedocument.wordprocessingml.document"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"},",\n"]],["span",{"class":"line","line":14},["span",{"class":"sMK4o"},"    ],\n"]],["span",{"class":"line","line":15},["span",{"class":"sMK4o"},"],\n"]]]],["p",{},"Controls file upload behavior. Set ",["code",{},"enabled"]," to ",["code",{},"false"]," to remove the attachment UI entirely. The ",["code",{},"max_size"]," is in kilobytes (default 10 MB)."],["h2",{"id":"broadcasting"},"Broadcasting"],["pre",{"className":"language-php shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","code":"'broadcasting' => [\n    'enabled' => false,\n    'channel_prefix' => 'comments',\n],\n","language":"php","meta":"","style":""},["code",{"__ignoreMap":""},["span",{"class":"line","line":1},["span",{"class":"sMK4o"},"'"],["span",{"class":"sfazB"},"broadcasting"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," [\n"]],["span",{"class":"line","line":2},["span",{"class":"sMK4o"},"    '"],["span",{"class":"sfazB"},"enabled"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," false,\n"]],["span",{"class":"line","line":3},["span",{"class":"sMK4o"},"    '"],["span",{"class":"sfazB"},"channel_prefix"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," '"],["span",{"class":"sfazB"},"comments"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"},",\n"]],["span",{"class":"line","line":4},["span",{"class":"sMK4o"},"],\n"]]]],["p",{},"When enabled, comment events are broadcast on private channels using the format ",["code",{},"{prefix}.{commentable_type}.{commentable_id}"],". Requires Laravel Echo and a broadcasting driver."],["h2",{"id":"polling"},"Polling"],["pre",{"className":"language-php shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","code":"'polling' => [\n    'interval' => '10s',\n],\n","language":"php","meta":"","style":""},["code",{"__ignoreMap":""},["span",{"class":"line","line":1},["span",{"class":"sMK4o"},"'"],["span",{"class":"sfazB"},"polling"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," [\n"]],["span",{"class":"line","line":2},["span",{"class":"sMK4o"},"    '"],["span",{"class":"sfazB"},"interval"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," '"],["span",{"class":"sfazB"},"10s"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"},",\n"]],["span",{"class":"line","line":3},["span",{"class":"sMK4o"},"],\n"]]]],["p",{},"When broadcasting is disabled, the Livewire component polls for new comments at this interval. Set to ",["code",{},"null"]," to disable polling."],["h2",{"id":"custom-user-resolution"},"Custom User Resolution"],["p",{},"Override how the authenticated user is resolved:"],["pre",{"className":"language-php shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","code":"use Relaticle\\Comments\\Config;\n\n// In AppServiceProvider::boot()\nConfig::resolveAuthenticatedUserUsing(function () {\n    return auth()->user();\n});\n","language":"php","meta":"","style":""},["code",{"__ignoreMap":""},["span",{"class":"line","line":1},["span",{"class":"sbssI"},"use"],["span",{"class":"sTEyZ"}," Relaticle"],["span",{"class":"sMK4o"},"\\"],["span",{"class":"sTEyZ"},"Comments"],["span",{"class":"sMK4o"},"\\"],["span",{"class":"sTEyZ"},"Config"],["span",{"class":"sMK4o"},";\n"]],["span",{"class":"line","line":2},["span",{"emptyLinePlaceholder":true},"\n"]],["span",{"class":"line","line":3},["span",{"class":"sHwdD"},"// In AppServiceProvider::boot()\n"]],["span",{"class":"line","line":4},["span",{"class":"sBMFI"},"Config"],["span",{"class":"sMK4o"},"::"],["span",{"class":"s2Zo4"},"resolveAuthenticatedUserUsing"],["span",{"class":"sMK4o"},"("],["span",{"class":"spNyl"},"function"],["span",{"class":"sMK4o"}," ()"],["span",{"class":"sMK4o"}," {\n"]],["span",{"class":"line","line":5},["span",{"class":"s7zQu"},"    return"],["span",{"class":"s2Zo4"}," auth"],["span",{"class":"sMK4o"},"()->"],["span",{"class":"s2Zo4"},"user"],["span",{"class":"sMK4o"},"();\n"]],["span",{"class":"line","line":6},["span",{"class":"sMK4o"},"});\n"]]]],["p",{},"This is useful for multi-guard applications or custom authentication flows."],["style",{},"html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}"]],"toc":{"title":"","searchDepth":2,"depth":2,"links":[{"id":"table-name","depth":2,"text":"Table Name"},{"id":"models","depth":2,"text":"Models"},{"id":"policy","depth":2,"text":"Policy"},{"id":"threading","depth":2,"text":"Threading"},{"id":"pagination","depth":2,"text":"Pagination"},{"id":"reactions","depth":2,"text":"Reactions"},{"id":"mentions","depth":2,"text":"Mentions"},{"id":"editor-toolbar","depth":2,"text":"Editor Toolbar"},{"id":"notifications","depth":2,"text":"Notifications"},{"id":"subscriptions","depth":2,"text":"Subscriptions"},{"id":"attachments","depth":2,"text":"Attachments"},{"id":"broadcasting","depth":2,"text":"Broadcasting"},{"id":"polling","depth":2,"text":"Polling"},{"id":"custom-user-resolution","depth":2,"text":"Custom User Resolution"}]}},"meta":{},"__metadata":{},"path":"/essentials/configuration","stem":"2.essentials/1.configuration","extension":"md"}


id: docs/2.essentials/5.attachments.md
checksum: b8052d6c9d96145f4dda37138d97c914
__hash__: RxIAxYrlgKw9A5HF9fskyQYYAQ2wKCwGerjkmgLbZkk
value:
{"id":"docs/2.essentials/5.attachments.md","title":"Attachments","description":"File uploads for comments.","navigation":{"icon":"i-lucide-paperclip"},"seo":{"description":"Configure file attachments for comments.","title":"Attachments"},"body":{"type":"minimark","value":[["h2",{"id":"overview"},"Overview"],["p",{},"Comments support file attachments for both images and documents. Images are displayed inline within the comment body, while documents appear as downloadable links."],["h2",{"id":"configuration"},"Configuration"],["pre",{"className":"language-php shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","code":"// config/comments.php\n'attachments' => [\n    'enabled' => true,\n    'disk' => 'public',\n    'max_size' => 10240, // KB (10 MB)\n    'allowed_types' => [\n        'image/jpeg',\n        'image/png',\n        'image/gif',\n        'image/webp',\n        'application/pdf',\n        'text/plain',\n        'application/msword',\n        'application/vnd.openxmlformats-officedocument.wordprocessingml.document',\n    ],\n],\n","language":"php","meta":"","style":""},["code",{"__ignoreMap":""},["span",{"class":"line","line":1},["span",{"class":"sHwdD"},"// config/comments.php\n"]],["span",{"class":"line","line":2},["span",{"class":"sMK4o"},"'"],["span",{"class":"sfazB"},"attachments"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," [\n"]],["span",{"class":"line","line":3},["span",{"class":"sMK4o"},"    '"],["span",{"class":"sfazB"},"enabled"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," true,\n"]],["span",{"class":"line","line":4},["span",{"class":"sMK4o"},"    '"],["span",{"class":"sfazB"},"disk"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," '"],["span",{"class":"sfazB"},"public"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"},",\n"]],["span",{"class":"line","line":5},["span",{"class":"sMK4o"},"    '"],["span",{"class":"sfazB"},"max_size"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sbssI"}," 10240"],["span",{"class":"sMK4o"},","],["span",{"class":"sHwdD"}," // KB (10 MB)\n"]],["span",{"class":"line","line":6},["span",{"class":"sMK4o"},"    '"],["span",{"class":"sfazB"},"allowed_types"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," [\n"]],["span",{"class":"line","line":7},["span",{"class":"sMK4o"},"        '"],["span",{"class":"sfazB"},"image/jpeg"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"},",\n"]],["span",{"class":"line","line":8},["span",{"class":"sMK4o"},"        '"],["span",{"class":"sfazB"},"image/png"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"},",\n"]],["span",{"class":"line","line":9},["span",{"class":"sMK4o"},"        '"],["span",{"class":"sfazB"},"image/gif"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"},",\n"]],["span",{"class":"line","line":10},["span",{"class":"sMK4o"},"        '"],["span",{"class":"sfazB"},"image/webp"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"},",\n"]],["span",{"class":"line","line":11},["span",{"class":"sMK4o"},"        '"],["span",{"class":"sfazB"},"application/pdf"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"},",\n"]],["span",{"class":"line","line":12},["span",{"class":"sMK4o"},"        '"],["span",{"class":"sfazB"},"text/plain"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"},",\n"]],["span",{"class":"line","line":13},["span",{"class":"sMK4o"},"        '"],["span",{"class":"sfazB"},"application/msword"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"},",\n"]],["span",{"class":"line","line":14},["span",{"class":"sMK4o"},"        '"],["span",{"class":"sfazB"},"application/vnd.openxmlformats-officedocument.wordprocessingml.document"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"},",\n"]],["span",{"class":"line","line":15},["span",{"class":"sMK4o"},"    ],\n"]],["span",{"class":"line","line":16},["span",{"class":"sMK4o"},"],\n"]]]],["table",{},["thead",{},["tr",{},["th",{},"Key"],["th",{},"Default"],["th",{},"Description"]]],["tbody",{},["tr",{},["td",{},["code",{},"enabled"]],["td",{},["code",{},"true"]],["td",{},"Show/hide the attachment upload UI"]],["tr",{},["td",{},["code",{},"disk"]],["td",{},["code",{},"'public'"]],["td",{},"Laravel filesystem disk for storage"]],["tr",{},["td",{},["code",{},"max_size"]],["td",{},["code",{},"10240"]],["td",{},"Maximum file size in kilobytes"]],["tr",{},["td",{},["code",{},"allowed_types"]],["td",{},"images, pdf, text, word"],["td",{},"Array of allowed MIME types"]]]],["h2",{"id":"disabling-attachments"},"Disabling Attachments"],["pre",{"className":"language-php shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","code":"'attachments' => [\n    'enabled' => false,\n],\n","language":"php","meta":"","style":""},["code",{"__ignoreMap":""},["span",{"class":"line","line":1},["span",{"class":"sMK4o"},"'"],["span",{"class":"sfazB"},"attachments"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," [\n"]],["span",{"class":"line","line":2},["span",{"class":"sMK4o"},"    '"],["span",{"class":"sfazB"},"enabled"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," false,\n"]],["span",{"class":"line","line":3},["span",{"class":"sMK4o"},"],\n"]]]],["p",{},"This removes the file upload UI from the comment form entirely."],["h2",{"id":"storage"},"Storage"],["p",{},"Attachments are stored via Livewire's file upload mechanism. Each attachment record tracks:"],["ul",{},["li",{},["code",{},"file_path"]," -- Path on the configured disk"],["li",{},["code",{},"original_name"]," -- Original filename for display"],["li",{},["code",{},"mime_type"]," -- MIME type for rendering decisions"],["li",{},["code",{},"size"]," -- File size in bytes"],["li",{},["code",{},"disk"]," -- Storage disk name"]],["p",{},"When a comment is deleted, its attachments are cascade deleted from the database. The physical files are removed from the disk."],["h2",{"id":"helper-methods"},"Helper Methods"],["p",{},"The ",["code",{},"CommentAttachment"]," model provides:"],["pre",{"className":"language-php shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","code":"$attachment->isImage();       // Check if attachment is an image\n$attachment->url();           // Get the storage URL\n$attachment->formattedSize(); // Human-readable size (e.g., \"2.5 MB\")\n","language":"php","meta":"","style":""},["code",{"__ignoreMap":""},["span",{"class":"line","line":1},["span",{"class":"sMK4o"},"$"],["span",{"class":"sTEyZ"},"attachment"],["span",{"class":"sMK4o"},"->"],["span",{"class":"s2Zo4"},"isImage"],["span",{"class":"sMK4o"},"();"],["span",{"class":"sHwdD"},"       // Check if attachment is an image\n"]],["span",{"class":"line","line":2},["span",{"class":"sMK4o"},"$"],["span",{"class":"sTEyZ"},"attachment"],["span",{"class":"sMK4o"},"->"],["span",{"class":"s2Zo4"},"url"],["span",{"class":"sMK4o"},"();"],["span",{"class":"sHwdD"},"           // Get the storage URL\n"]],["span",{"class":"line","line":3},["span",{"class":"sMK4o"},"$"],["span",{"class":"sTEyZ"},"attachment"],["span",{"class":"sMK4o"},"->"],["span",{"class":"s2Zo4"},"formattedSize"],["span",{"class":"sMK4o"},"();"],["span",{"class":"sHwdD"}," // Human-readable size (e.g., \"2.5 MB\")\n"]]]],["style",{},"html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}"]],"toc":{"title":"","searchDepth":2,"depth":2,"links":[{"id":"overview","depth":2,"text":"Overview"},{"id":"configuration","depth":2,"text":"Configuration"},{"id":"disabling-attachments","depth":2,"text":"Disabling Attachments"},{"id":"storage","depth":2,"text":"Storage"},{"id":"helper-methods","depth":2,"text":"Helper Methods"}]}},"meta":{},"__metadata":{},"path":"/essentials/attachments","stem":"2.essentials/5.attachments","extension":"md"}


id: docs/2.essentials/4.reactions.md
checksum: 4caf4d63770f0b4ce4b0ffc6d01404ad
__hash__: mqtOqwsslZkE2pUZO5eEgNtSv3fTprs_8HOg5OWcPY0
value:
{"id":"docs/2.essentials/4.reactions.md","title":"Reactions","description":"Emoji reactions on comments.","navigation":{"icon":"i-lucide-smile"},"seo":{"description":"Configure emoji reactions for comments.","title":"Reactions"},"body":{"type":"minimark","value":[["h2",{"id":"default-reactions"},"Default Reactions"],["p",{},"Six emoji reactions are available out of the box:"],["table",{},["thead",{},["tr",{},["th",{},"Key"],["th",{},"Emoji"],["th",{},"Label"]]],["tbody",{},["tr",{},["td",{},["code",{},"thumbs_up"]],["td",{},":thumbsup:"],["td",{},"Like"]],["tr",{},["td",{},["code",{},"heart"]],["td",{},"❤️"],["td",{},"Love"]],["tr",{},["td",{},["code",{},"celebrate"]],["td",{},"🎉"],["td",{},"Celebrate"]],["tr",{},["td",{},["code",{},"laugh"]],["td",{},"😄"],["td",{},"Laugh"]],["tr",{},["td",{},["code",{},"thinking"]],["td",{},"🤔"],["td",{},"Thinking"]],["tr",{},["td",{},["code",{},"sad"]],["td",{},"😢"],["td",{},"Sad"]]]],["h2",{"id":"how-reactions-work"},"How Reactions Work"],["ul",{},["li",{},"Each user can add one reaction of each type per comment"],["li",{},"Clicking the same reaction again removes it (toggle behavior)"],["li",{},"The reaction summary shows which users reacted with each emoji"],["li",{},"A ",["code",{},"CommentReacted"]," event is dispatched with ",["code",{},"action: 'added'"]," or ",["code",{},"'removed'"]]],["h2",{"id":"customizing-reactions"},"Customizing Reactions"],["p",{},"Override the emoji set in your config:"],["pre",{"className":"language-php shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","code":"// config/comments.php\n'reactions' => [\n    'emoji_set' => [\n        'thumbs_up' => \"\\u{1F44D}\",\n        'thumbs_down' => \"\\u{1F44E}\",\n        'heart' => \"\\u{2764}\\u{FE0F}\",\n        'fire' => \"\\u{1F525}\",\n        'eyes' => \"\\u{1F440}\",\n    ],\n],\n","language":"php","meta":"","style":""},["code",{"__ignoreMap":""},["span",{"class":"line","line":1},["span",{"class":"sHwdD"},"// config/comments.php\n"]],["span",{"class":"line","line":2},["span",{"class":"sMK4o"},"'"],["span",{"class":"sfazB"},"reactions"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," [\n"]],["span",{"class":"line","line":3},["span",{"class":"sMK4o"},"    '"],["span",{"class":"sfazB"},"emoji_set"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," [\n"]],["span",{"class":"line","line":4},["span",{"class":"sMK4o"},"        '"],["span",{"class":"sfazB"},"thumbs_up"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," \""],["span",{"class":"sTEyZ"},"\\u{1F44D}"],["span",{"class":"sMK4o"},"\""],["span",{"class":"sMK4o"},",\n"]],["span",{"class":"line","line":5},["span",{"class":"sMK4o"},"        '"],["span",{"class":"sfazB"},"thumbs_down"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," \""],["span",{"class":"sTEyZ"},"\\u{1F44E}"],["span",{"class":"sMK4o"},"\""],["span",{"class":"sMK4o"},",\n"]],["span",{"class":"line","line":6},["span",{"class":"sMK4o"},"        '"],["span",{"class":"sfazB"},"heart"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," \""],["span",{"class":"sTEyZ"},"\\u{2764}\\u{FE0F}"],["span",{"class":"sMK4o"},"\""],["span",{"class":"sMK4o"},",\n"]],["span",{"class":"line","line":7},["span",{"class":"sMK4o"},"        '"],["span",{"class":"sfazB"},"fire"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," \""],["span",{"class":"sTEyZ"},"\\u{1F525}"],["span",{"class":"sMK4o"},"\""],["span",{"class":"sMK4o"},",\n"]],["span",{"class":"line","line":8},["span",{"class":"sMK4o"},"        '"],["span",{"class":"sfazB"},"eyes"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," \""],["span",{"class":"sTEyZ"},"\\u{1F440}"],["span",{"class":"sMK4o"},"\""],["span",{"class":"sMK4o"},",\n"]],["span",{"class":"line","line":9},["span",{"class":"sMK4o"},"    ],\n"]],["span",{"class":"line","line":10},["span",{"class":"sMK4o"},"],\n"]]]],["p",{},"Keys are stored in the database. If you change a key, existing reactions with the old key will no longer display."],["h2",{"id":"storage"},"Storage"],["p",{},"Reactions are stored in the ",["code",{},"comment_reactions"]," table with a unique constraint on ",["code",{},"(comment_id, user_id, user_type, reaction)"],", ensuring one reaction of each type per user per comment."],["style",{},"html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}"]],"toc":{"title":"","searchDepth":2,"depth":2,"links":[{"id":"default-reactions","depth":2,"text":"Default Reactions"},{"id":"how-reactions-work","depth":2,"text":"How Reactions Work"},{"id":"customizing-reactions","depth":2,"text":"Customizing Reactions"},{"id":"storage","depth":2,"text":"Storage"}]}},"meta":{},"__metadata":{},"path":"/essentials/reactions","stem":"2.essentials/4.reactions","extension":"md"}


id: docs/2.essentials/7.database-schema.md
checksum: 0bf366939383bc4727f9fb9876e6ba6e
__hash__: 01MFdGkeBjjHRoC15avlOGEWtwiZ6690yvDEA9-NlOI
value:
{"id":"docs/2.essentials/7.database-schema.md","title":"Database Schema","description":"Tables, relationships, and indexes used by the Comments package.","navigation":{"icon":"i-lucide-database"},"seo":{"description":"Database schema reference for the Comments package.","title":"Database Schema"},"body":{"type":"minimark","value":[["h2",{"id":"tables"},"Tables"],["p",{},"Five tables are created by the package migrations."],["h3",{"id":"comments"},"comments"],["p",{},"The main comments table with polymorphic relationships and threading support."],["table",{},["thead",{},["tr",{},["th",{},"Column"],["th",{},"Type"],["th",{},"Description"]]],["tbody",{},["tr",{},["td",{},["code",{},"id"]],["td",{},"bigint"],["td",{},"Primary key"]],["tr",{},["td",{},["code",{},"commentable_type"]],["td",{},"string"],["td",{},"Polymorphic model type"]],["tr",{},["td",{},["code",{},"commentable_id"]],["td",{},"bigint"],["td",{},"Polymorphic model ID"]],["tr",{},["td",{},["code",{},"user_type"]],["td",{},"string"],["td",{},"Commenter model type"]],["tr",{},["td",{},["code",{},"user_id"]],["td",{},"bigint"],["td",{},"Commenter model ID"]],["tr",{},["td",{},["code",{},"parent_id"]],["td",{},"bigint (nullable)"],["td",{},"Parent comment for replies"]],["tr",{},["td",{},["code",{},"body"]],["td",{},"text"],["td",{},"HTML comment content"]],["tr",{},["td",{},["code",{},"edited_at"]],["td",{},"timestamp (nullable)"],["td",{},"When the comment was last edited"]],["tr",{},["td",{},["code",{},"deleted_at"]],["td",{},"timestamp (nullable)"],["td",{},"Soft delete timestamp"]],["tr",{},["td",{},["code",{},"created_at"]],["td",{},"timestamp"],["td",{}]],["tr",{},["td",{},["code",{},"updated_at"]],["td",{},"timestamp"],["td",{}]]]],["p",{},["strong",{},"Indexes:"]," ",["code",{},"(commentable_type, commentable_id, parent_id)"]],["h3",{"id":"comment_reactions"},"comment_reactions"],["p",{},"Tracks emoji reactions per user per comment."],["table",{},["thead",{},["tr",{},["th",{},"Column"],["th",{},"Type"],["th",{},"Description"]]],["tbody",{},["tr",{},["td",{},["code",{},"id"]],["td",{},"bigint"],["td",{},"Primary key"]],["tr",{},["td",{},["code",{},"comment_id"]],["td",{},"bigint"],["td",{},"Foreign key to comments"]],["tr",{},["td",{},["code",{},"user_type"]],["td",{},"string"],["td",{},"Reactor model type"]],["tr",{},["td",{},["code",{},"user_id"]],["td",{},"bigint"],["td",{},"Reactor model ID"]],["tr",{},["td",{},["code",{},"reaction"]],["td",{},"string"],["td",{},"Reaction key (e.g., ",["code",{},"thumbs_up"],")"]],["tr",{},["td",{},["code",{},"created_at"]],["td",{},"timestamp"],["td",{}]]]],["p",{},["strong",{},"Unique constraint:"]," ",["code",{},"(comment_id, user_id, user_type, reaction)"]],["h3",{"id":"comment_mentions"},"comment_mentions"],["p",{},"Tracks @mentioned users per comment."],["table",{},["thead",{},["tr",{},["th",{},"Column"],["th",{},"Type"],["th",{},"Description"]]],["tbody",{},["tr",{},["td",{},["code",{},"id"]],["td",{},"bigint"],["td",{},"Primary key"]],["tr",{},["td",{},["code",{},"comment_id"]],["td",{},"bigint"],["td",{},"Foreign key to comments"]],["tr",{},["td",{},["code",{},"user_type"]],["td",{},"string"],["td",{},"Mentioned user model type"]],["tr",{},["td",{},["code",{},"user_id"]],["td",{},"bigint"],["td",{},"Mentioned user model ID"]],["tr",{},["td",{},["code",{},"created_at"]],["td",{},"timestamp"],["td",{}]]]],["p",{},["strong",{},"Unique constraint:"]," ",["code",{},"(comment_id, user_id, user_type)"]],["h3",{"id":"comment_subscriptions"},"comment_subscriptions"],["p",{},"Tracks which users are subscribed to comment threads on specific models."],["table",{},["thead",{},["tr",{},["th",{},"Column"],["th",{},"Type"],["th",{},"Description"]]],["tbody",{},["tr",{},["td",{},["code",{},"id"]],["td",{},"bigint"],["td",{},"Primary key"]],["tr",{},["td",{},["code",{},"commentable_type"]],["td",{},"string"],["td",{},"Subscribed model type"]],["tr",{},["td",{},["code",{},"commentable_id"]],["td",{},"bigint"],["td",{},"Subscribed model ID"]],["tr",{},["td",{},["code",{},"user_type"]],["td",{},"string"],["td",{},"Subscriber model type"]],["tr",{},["td",{},["code",{},"user_id"]],["td",{},"bigint"],["td",{},"Subscriber model ID"]],["tr",{},["td",{},["code",{},"created_at"]],["td",{},"timestamp"],["td",{}]]]],["p",{},["strong",{},"Unique constraint:"]," ",["code",{},"(commentable_type, commentable_id, user_type, user_id)"]],["h3",{"id":"comment_attachments"},"comment_attachments"],["p",{},"Stores file attachment metadata for comments."],["table",{},["thead",{},["tr",{},["th",{},"Column"],["th",{},"Type"],["th",{},"Description"]]],["tbody",{},["tr",{},["td",{},["code",{},"id"]],["td",{},"bigint"],["td",{},"Primary key"]],["tr",{},["td",{},["code",{},"comment_id"]],["td",{},"bigint"],["td",{},"Foreign key to comments"]],["tr",{},["td",{},["code",{},"file_path"]],["td",{},"string"],["td",{},"Path on the storage disk"]],["tr",{},["td",{},["code",{},"original_name"]],["td",{},"string"],["td",{},"Original uploaded filename"]],["tr",{},["td",{},["code",{},"mime_type"]],["td",{},"string"],["td",{},"File MIME type"]],["tr",{},["td",{},["code",{},"size"]],["td",{},"bigint"],["td",{},"File size in bytes"]],["tr",{},["td",{},["code",{},"disk"]],["td",{},"string"],["td",{},"Laravel filesystem disk"]],["tr",{},["td",{},["code",{},"created_at"]],["td",{},"timestamp"],["td",{}]],["tr",{},["td",{},["code",{},"updated_at"]],["td",{},"timestamp"],["td",{}]]]],["h2",{"id":"relationships"},"Relationships"],["pre",{"className":["language-text"],"code":"Commentable Model (e.g., Project)\n  └── comments (morphMany)\n        ├── user (morphTo → User)\n        ├── parent (belongsTo → Comment)\n        ├── replies (hasMany → Comment)\n        ├── reactions (hasMany → CommentReaction)\n        ├── attachments (hasMany → CommentAttachment)\n        └── mentions (morphToMany → User)\n","language":"text"},["code",{"__ignoreMap":""},"Commentable Model (e.g., Project)\n  └── comments (morphMany)\n        ├── user (morphTo → User)\n        ├── parent (belongsTo → Comment)\n        ├── replies (hasMany → Comment)\n        ├── reactions (hasMany → CommentReaction)\n        ├── attachments (hasMany → CommentAttachment)\n        └── mentions (morphToMany → User)\n"]],["p",{},"All relationships are polymorphic, allowing the same comment system to work across any number of models in your application."]],"toc":{"title":"","searchDepth":2,"depth":2,"links":[{"id":"tables","depth":2,"text":"Tables","children":[{"id":"comments","depth":3,"text":"comments"},{"id":"comment_reactions","depth":3,"text":"comment_reactions"},{"id":"comment_mentions","depth":3,"text":"comment_mentions"},{"id":"comment_subscriptions","depth":3,"text":"comment_subscriptions"},{"id":"comment_attachments","depth":3,"text":"comment_attachments"}]},{"id":"relationships","depth":2,"text":"Relationships"}]}},"meta":{},"__metadata":{},"path":"/essentials/database-schema","stem":"2.essentials/7.database-schema","extension":"md"}


id: landing/index.md
value: 694063b2c6e70aaad90cf9e89520a232
__hash__: G8T5wybGD8gLji3SbQJKS1gkRhUlMRAMhpT_WhqBWIQ
checksum:
{"id":"landing/index.md","title":"","description":"","seo":{"title":"Filament Comments System","description":"A full-featured commenting system for Filament panels with threaded replies, @mentions, emoji reactions, file attachments, and real-time updates.","ogImage":"/og-image.png"},"body":{"type":"minimark","value":[["u-page-hero",{},["template",{"v-slot:title":""},"Comments"],["template",{"v-slot:description":""},["p",{},"A full-featured commenting system for Filament panels with threaded replies, @mentions, emoji reactions, and real-time updates."],["p",{},"Drop-in integration with any Filament resource."]],["template",{"v-slot:links":""},["u-button",{"color":"neutral","size":"xl","to":"/getting-started/installation","trailing-icon":"i-lucide-arrow-right"},"Get started"],["u-button",{"color":"neutral","size":"xl","to":"https://github.com/relaticle/comments","icon":"simple-icons:github","variant":"outline"},"GitHub"]]],["u-page-section",{},["template",{"v-slot:title":""},"Why choose Comments?"],["template",{"v-slot:features":""},["u-page-feature",{"icon":"i-lucide-messages-square"},["template",{"v-slot:title":""},"Threaded Replies"],["template",{"v-slot:description":""},"Nested comment threads with configurable depth limits. Users can reply to specific comments creating organized discussions."]],["u-page-feature",{"icon":"i-lucide-at-sign"},["template",{"v-slot:title":""},"@Mentions"],["template",{"v-slot:description":""},"Autocomplete user mentions with a customizable resolver interface. Dispatches events for notification handling."]],["u-page-feature",{"icon":"i-lucide-smile"},["template",{"v-slot:title":""},"Emoji Reactions"],["template",{"v-slot:description":""},"Six built-in emoji reactions with a configurable set. Users can react to comments with a single click."]],["u-page-feature",{"icon":"i-lucide-paperclip"},["template",{"v-slot:title":""},"File Attachments"],["template",{"v-slot:description":""},"Upload images and documents to comments with configurable storage, size limits, and MIME type validation."]],["u-page-feature",{"icon":"i-lucide-radio"},["template",{"v-slot:title":""},"Real-time Updates"],["template",{"v-slot:description":""},"Optional broadcasting via private channels with automatic polling fallback. Comments stay in sync across sessions."]],["u-page-feature",{"icon":"i-lucide-puzzle"},["template",{"v-slot:title":""},"Full Filament Integration"],["template",{"v-slot:description":""},"Three integration patterns: slide-over action, table row action, and infolist entry. Works with any Filament resource."]]]],["u-page-section",{},["template",{"v-slot:title":""},"Our Ecosystem"],["template",{"v-slot:description":""},"Extend your Laravel applications with our ecosystem of complementary tools"],["card-group",{},["card",{"icon":"i-simple-icons-laravel","target":"_blank","title":"FilaForms","to":"https://filaforms.app"},"Visual form builder for all your public-facing forms."],["card",{"icon":"i-lucide-sliders","target":"_blank","title":"Custom Fields","to":"https://relaticle.github.io/custom-fields"},"Let users add custom fields to any model without code changes."]]]],"toc":{"title":"","searchDepth":2,"depth":2,"links":[]}},"meta":{},"__metadata":{},"path":"/","stem":"index","extension":"md"}


# _content_docs

id: docs/1.getting-started/1.introduction.md
title: Introduction
description: A full-featured commenting system for Filament panels.
extension: md
meta: {}
navigation: {"icon":"i-lucide-home"}
path: /getting-started/introduction
stem: 1.getting-started/1.introduction
__hash__: 6eZJf_TpqGxPgrJEFN3Q_zLaPhqa1QmWrn9m5QqijF0
body:
{"type":"minimark","value":[["p",{},"Welcome to ",["strong",{},"Comments"],", a powerful Laravel package that adds a full-featured commenting system to any Filament panel."],["h2",{"id":"what-is-comments"},"What is Comments?"],["p",{},"Comments provides polymorphic commenting on any Eloquent model with deep Filament integration. Add threaded discussions, @mentions, emoji reactions, file attachments, and real-time notifications to your admin panel with minimal setup."],["h2",{"id":"why-choose-comments"},"Why Choose Comments?"],["card-group",{},["card",{"icon":"i-lucide-messages-square","title":"Threaded Discussions"},"Nested replies with configurable depth limits keep conversations organized and easy to follow."],["card",{"icon":"i-lucide-clock","title":"Quick Setup"},"Add traits to your models, register the plugin, and you have a working comment system in minutes."],["card",{"icon":"i-lucide-puzzle","title":"3 Integration Patterns"},"Use as a slide-over action, table row action, or inline infolist entry - whatever fits your resource."],["card",{"icon":"i-lucide-bell","title":"Built-in Notifications"},"Database and mail notifications with subscription management and auto-subscribe for authors and mentioned users."]]],"toc":{"title":"","searchDepth":2,"depth":2,"links":[{"id":"what-is-comments","depth":2,"text":"What is Comments?"},{"id":"why-choose-comments","depth":2,"text":"Why Choose Comments?"}]}}

seo:
{"title":"Introduction","description":"Learn about Comments - a full-featured commenting system for Filament panels with threaded replies, @mentions, emoji reactions, and real-time updates.","ogImage":"/preview.png"}


id: docs/1.getting-started/2.installation.md
title: Installation
description: Get started with Comments in minutes.
extension: md
meta: {}
navigation: {"icon":"i-lucide-download"}
path: /getting-started/installation
stem: 1.getting-started/2.installation
__hash__: P-D2nmzwgaER3VhGsRqb9LLvO_CS3iwjGQuk2_o2Svc
body:
{"type":"minimark","value":[["h2",{"id":"requirements"},"Requirements"],["ul",{},["li",{},["strong",{},"PHP:"]," 8.2+"],["li",{},["strong",{},"Laravel:"]," 12+"],["li",{},["strong",{},"Filament:"]," 4.x / 5.x"],["li",{},["strong",{},"Livewire:"]," 3.5+ / 4.x"]],["h2",{"id":"quick-setup"},"Quick Setup"],["steps",{},["h3",{"id":"install-package"},"Install Package"],["pre",{"className":"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","code":"composer require relaticle/comments\n","filename":"Terminal","language":"bash","meta":"","style":""},["code",{"__ignoreMap":""},["span",{"class":"line","line":1},["span",{"class":"sBMFI"},"composer"],["span",{"class":"sfazB"}," require"],["span",{"class":"sfazB"}," relaticle/comments\n"]]]],["h3",{"id":"publish-and-run-migrations"},"Publish and Run Migrations"],["pre",{"className":"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","code":"php artisan vendor:publish --tag=comments-migrations\nphp artisan migrate\n","filename":"Terminal","language":"bash","meta":"","style":""},["code",{"__ignoreMap":""},["span",{"class":"line","line":1},["span",{"class":"sBMFI"},"php"],["span",{"class":"sfazB"}," artisan"],["span",{"class":"sfazB"}," vendor:publish"],["span",{"class":"sfazB"}," --tag=comments-migrations\n"]],["span",{"class":"line","line":2},["span",{"class":"sBMFI"},"php"],["span",{"class":"sfazB"}," artisan"],["span",{"class":"sfazB"}," migrate\n"]]]],["h3",{"id":"include-css-assets"},"Include CSS Assets"],["p",{},"Prerequisite: You need a custom Filament theme to include the Comments styles."],["alert",{"type":"warning"},"If you haven't set up a custom theme for Filament, follow the ",["a",{"href":"https://filamentphp.com/docs/5.x/styling/overview#creating-a-custom-theme","rel":["nofollow"]},"Filament Docs"]," first."],["p",{},"Add the plugin's views to your theme CSS file:"],["pre",{"className":"language-css shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","code":"@source \"../../../../vendor/relaticle/comments/resources/views/**/*.blade.php\";\n","filename":"resources/css/filament/admin/theme.css","language":"css","meta":"","style":""},["code",{"__ignoreMap":""},["span",{"class":"line","line":1},["span",{"class":"s7zQu"},"@source"],["span",{"class":"sTEyZ"}," \"../../../../vendor/relaticle/comments/resources/views/**/*.blade.php\""],["span",{"class":"sMK4o"},";\n"]]]],["h3",{"id":"register-the-plugin"},"Register the Plugin"],["pre",{"className":"language-php shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","code":"use Relaticle\\Comments\\CommentsPlugin;\n\npublic function panel(Panel $panel): Panel\n{\n    return $panel\n        ->plugins([\n            CommentsPlugin::make(),\n        ]);\n}\n","filename":"AdminPanelProvider.php","language":"php","meta":"","style":""},["code",{"__ignoreMap":""},["span",{"class":"line","line":1},["span",{"class":"sbssI"},"use"],["span",{"class":"sTEyZ"}," Relaticle"],["span",{"class":"sMK4o"},"\\"],["span",{"class":"sTEyZ"},"Comments"],["span",{"class":"sMK4o"},"\\"],["span",{"class":"sTEyZ"},"CommentsPlugin"],["span",{"class":"sMK4o"},";\n"]],["span",{"class":"line","line":2},["span",{"emptyLinePlaceholder":true},"\n"]],["span",{"class":"line","line":3},["span",{"class":"spNyl"},"public"],["span",{"class":"spNyl"}," function"],["span",{"class":"s2Zo4"}," panel"],["span",{"class":"sMK4o"},"("],["span",{"class":"sBMFI"},"Panel"],["span",{"class":"sMK4o"}," $"],["span",{"class":"sTEyZ"},"panel"],["span",{"class":"sMK4o"},"):"],["span",{"class":"sBMFI"}," Panel\n"]],["span",{"class":"line","line":4},["span",{"class":"sMK4o"},"{\n"]],["span",{"class":"line","line":5},["span",{"class":"s7zQu"},"    return"],["span",{"class":"sMK4o"}," $"],["span",{"class":"sTEyZ"},"panel\n"]],["span",{"class":"line","line":6},["span",{"class":"sMK4o"},"        ->"],["span",{"class":"s2Zo4"},"plugins"],["span",{"class":"sMK4o"},"([\n"]],["span",{"class":"line","line":7},["span",{"class":"sBMFI"},"            CommentsPlugin"],["span",{"class":"sMK4o"},"::"],["span",{"class":"s2Zo4"},"make"],["span",{"class":"sMK4o"},"(),\n"]],["span",{"class":"line","line":8},["span",{"class":"sMK4o"},"        ]);\n"]],["span",{"class":"line","line":9},["span",{"class":"sMK4o"},"}\n"]]]],["h3",{"id":"set-up-your-models"},"Set Up Your Models"],["p",{},"Add the ",["code",{},"HasComments"]," trait to any model you want to comment on:"],["pre",{"className":"language-php shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","code":"use Relaticle\\Comments\\Concerns\\HasComments;\nuse Relaticle\\Comments\\Contracts\\Commentable;\n\nclass Project extends Model implements Commentable\n{\n    use HasComments;\n}\n","filename":"app/Models/Project.php","language":"php","meta":"","style":""},["code",{"__ignoreMap":""},["span",{"class":"line","line":1},["span",{"class":"sbssI"},"use"],["span",{"class":"sTEyZ"}," Relaticle"],["span",{"class":"sMK4o"},"\\"],["span",{"class":"sTEyZ"},"Comments"],["span",{"class":"sMK4o"},"\\"],["span",{"class":"sTEyZ"},"Concerns"],["span",{"class":"sMK4o"},"\\"],["span",{"class":"sTEyZ"},"HasComments"],["span",{"class":"sMK4o"},";\n"]],["span",{"class":"line","line":2},["span",{"class":"sbssI"},"use"],["span",{"class":"sTEyZ"}," Relaticle"],["span",{"class":"sMK4o"},"\\"],["span",{"class":"sTEyZ"},"Comments"],["span",{"class":"sMK4o"},"\\"],["span",{"class":"sTEyZ"},"Contracts"],["span",{"class":"sMK4o"},"\\"],["span",{"class":"sTEyZ"},"Commentable"],["span",{"class":"sMK4o"},";\n"]],["span",{"class":"line","line":3},["span",{"emptyLinePlaceholder":true},"\n"]],["span",{"class":"line","line":4},["span",{"class":"spNyl"},"class"],["span",{"class":"sBMFI"}," Project"],["span",{"class":"spNyl"}," extends"],["span",{"class":"sBMFI"}," Model"],["span",{"class":"spNyl"}," implements"],["span",{"class":"sBMFI"}," Commentable\n"]],["span",{"class":"line","line":5},["span",{"class":"sMK4o"},"{\n"]],["span",{"class":"line","line":6},["span",{"class":"sbssI"},"    use"],["span",{"class":"sTEyZ"}," HasComments"],["span",{"class":"sMK4o"},";\n"]],["span",{"class":"line","line":7},["span",{"class":"sMK4o"},"}\n"]]]],["p",{},"Add the ",["code",{},"IsCommenter"]," trait to your User model:"],["pre",{"className":"language-php shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","code":"use Relaticle\\Comments\\Concerns\\IsCommenter;\nuse Relaticle\\Comments\\Contracts\\Commenter;\n\nclass User extends Authenticatable implements Commenter\n{\n    use IsCommenter;\n}\n","filename":"app/Models/User.php","language":"php","meta":"","style":""},["code",{"__ignoreMap":""},["span",{"class":"line","line":1},["span",{"class":"sbssI"},"use"],["span",{"class":"sTEyZ"}," Relaticle"],["span",{"class":"sMK4o"},"\\"],["span",{"class":"sTEyZ"},"Comments"],["span",{"class":"sMK4o"},"\\"],["span",{"class":"sTEyZ"},"Concerns"],["span",{"class":"sMK4o"},"\\"],["span",{"class":"sTEyZ"},"IsCommenter"],["span",{"class":"sMK4o"},";\n"]],["span",{"class":"line","line":2},["span",{"class":"sbssI"},"use"],["span",{"class":"sTEyZ"}," Relaticle"],["span",{"class":"sMK4o"},"\\"],["span",{"class":"sTEyZ"},"Comments"],["span",{"class":"sMK4o"},"\\"],["span",{"class":"sTEyZ"},"Contracts"],["span",{"class":"sMK4o"},"\\"],["span",{"class":"sTEyZ"},"Commenter"],["span",{"class":"sMK4o"},";\n"]],["span",{"class":"line","line":3},["span",{"emptyLinePlaceholder":true},"\n"]],["span",{"class":"line","line":4},["span",{"class":"spNyl"},"class"],["span",{"class":"sBMFI"}," User"],["span",{"class":"spNyl"}," extends"],["span",{"class":"sBMFI"}," Authenticatable"],["span",{"class":"spNyl"}," implements"],["span",{"class":"sBMFI"}," Commenter\n"]],["span",{"class":"line","line":5},["span",{"class":"sMK4o"},"{\n"]],["span",{"class":"line","line":6},["span",{"class":"sbssI"},"    use"],["span",{"class":"sTEyZ"}," IsCommenter"],["span",{"class":"sMK4o"},";\n"]],["span",{"class":"line","line":7},["span",{"class":"sMK4o"},"}\n"]]]],["h3",{"id":"add-to-your-resources"},"Add to Your Resources"],["p",{},"Use the slide-over action on view or edit pages:"],["pre",{"className":"language-php shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","code":"use Relaticle\\Comments\\Filament\\Actions\\CommentsAction;\n\nprotected function getHeaderActions(): array\n{\n    return [\n        CommentsAction::make(),\n    ];\n}\n","filename":"app/Filament/Resources/ProjectResource/Pages/ViewProject.php","language":"php","meta":"","style":""},["code",{"__ignoreMap":""},["span",{"class":"line","line":1},["span",{"class":"sbssI"},"use"],["span",{"class":"sTEyZ"}," Relaticle"],["span",{"class":"sMK4o"},"\\"],["span",{"class":"sTEyZ"},"Comments"],["span",{"class":"sMK4o"},"\\"],["span",{"class":"sTEyZ"},"Filament"],["span",{"class":"sMK4o"},"\\"],["span",{"class":"sTEyZ"},"Actions"],["span",{"class":"sMK4o"},"\\"],["span",{"class":"sTEyZ"},"CommentsAction"],["span",{"class":"sMK4o"},";\n"]],["span",{"class":"line","line":2},["span",{"emptyLinePlaceholder":true},"\n"]],["span",{"class":"line","line":3},["span",{"class":"spNyl"},"protected"],["span",{"class":"spNyl"}," function"],["span",{"class":"s2Zo4"}," getHeaderActions"],["span",{"class":"sMK4o"},"():"],["span",{"class":"sbssI"}," array\n"]],["span",{"class":"line","line":4},["span",{"class":"sMK4o"},"{\n"]],["span",{"class":"line","line":5},["span",{"class":"s7zQu"},"    return"],["span",{"class":"sMK4o"}," [\n"]],["span",{"class":"line","line":6},["span",{"class":"sBMFI"},"        CommentsAction"],["span",{"class":"sMK4o"},"::"],["span",{"class":"s2Zo4"},"make"],["span",{"class":"sMK4o"},"(),\n"]],["span",{"class":"line","line":7},["span",{"class":"sMK4o"},"    ];\n"]],["span",{"class":"line","line":8},["span",{"class":"sMK4o"},"}\n"]]]]],["p",{},["strong",{},"Done!"]," Visit your Filament panel to see comments in action."],["h2",{"id":"optional-configuration"},"Optional Configuration"],["table",{},["thead",{},["tr",{},["th",{},"Command"],["th",{},"Action"]]],["tbody",{},["tr",{},["td",{},["code",{},"php artisan vendor:publish --tag=comments-config"]],["td",{},"Publish the configuration file"]],["tr",{},["td",{},["code",{},"php artisan vendor:publish --tag=comments-views"]],["td",{},"Publish the Blade views for customization"]],["tr",{},["td",{},["code",{},"php artisan vendor:publish --tag=comments-translations"]],["td",{},"Publish the translation files"]]]],["style",{},"html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}"]],"toc":{"title":"","searchDepth":2,"depth":2,"links":[{"id":"requirements","depth":2,"text":"Requirements"},{"id":"quick-setup","depth":2,"text":"Quick Setup","children":[{"id":"install-package","depth":3,"text":"Install Package"},{"id":"publish-and-run-migrations","depth":3,"text":"Publish and Run Migrations"},{"id":"include-css-assets","depth":3,"text":"Include CSS Assets"},{"id":"register-the-plugin","depth":3,"text":"Register the Plugin"},{"id":"set-up-your-models","depth":3,"text":"Set Up Your Models"},{"id":"add-to-your-resources","depth":3,"text":"Add to Your Resources"}]},{"id":"optional-configuration","depth":2,"text":"Optional Configuration"}]}}

seo:
{"description":"Install Comments and add commenting to your Filament resources.","ogImage":"/preview.png","title":"Installation"}


id: docs/1.getting-started/3.upgrading.md
title: Upgrading
description: Upgrade guide for Comments.
extension: md
meta: {}
navigation: {"icon":"i-lucide-arrow-up-circle"}
path: /getting-started/upgrading
seo: {"description":"How to upgrade Comments between versions.","title":"Upgrading"}
stem: 1.getting-started/3.upgrading
__hash__: WRPY70h_uCwuGQCscqg2hKh33EW3Mw7hxSY_P7K6bQI
body:
{"type":"minimark","value":[["h2",{"id":"_1x"},"1.x"],["p",{},"This is the initial release of Comments. Future upgrade guides will be documented here as new versions are released."]],"toc":{"title":"","searchDepth":2,"depth":2,"links":[{"id":"_1x","depth":2,"text":"1.x"}]}}


id: docs/2.essentials/1.configuration.md
title: Configuration
description: Configure threading, reactions, mentions, attachments, notifications, and more.
extension: md
meta: {}
navigation: {"icon":"i-lucide-settings"}
path: /essentials/configuration
stem: 2.essentials/1.configuration
__hash__: TvFOm5T-P3dGPliy66VKV_R_c9hzHMsR26iqUAm-DLc
body:
{"type":"minimark","value":[["p",{},"Publish the configuration file:"],["pre",{"className":"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","code":"php artisan vendor:publish --tag=comments-config\n","language":"bash","meta":"","style":""},["code",{"__ignoreMap":""},["span",{"class":"line","line":1},["span",{"class":"sBMFI"},"php"],["span",{"class":"sfazB"}," artisan"],["span",{"class":"sfazB"}," vendor:publish"],["span",{"class":"sfazB"}," --tag=comments-config\n"]]]],["p",{},"This creates ",["code",{},"config/comments.php"]," with all available options."],["h2",{"id":"table-name"},"Table Name"],["pre",{"className":"language-php shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","code":"'tables' => [\n    'comments' => 'comments',\n],\n","language":"php","meta":"","style":""},["code",{"__ignoreMap":""},["span",{"class":"line","line":1},["span",{"class":"sMK4o"},"'"],["span",{"class":"sfazB"},"tables"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," [\n"]],["span",{"class":"line","line":2},["span",{"class":"sMK4o"},"    '"],["span",{"class":"sfazB"},"comments"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," '"],["span",{"class":"sfazB"},"comments"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"},",\n"]],["span",{"class":"line","line":3},["span",{"class":"sMK4o"},"],\n"]]]],["p",{},"Change the table name if it conflicts with your application."],["h2",{"id":"models"},"Models"],["pre",{"className":"language-php shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","code":"'models' => [\n    'comment' => \\Relaticle\\Comments\\Comment::class,\n],\n\n'commenter' => [\n    'model' => \\App\\Models\\User::class,\n],\n","language":"php","meta":"","style":""},["code",{"__ignoreMap":""},["span",{"class":"line","line":1},["span",{"class":"sMK4o"},"'"],["span",{"class":"sfazB"},"models"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," [\n"]],["span",{"class":"line","line":2},["span",{"class":"sMK4o"},"    '"],["span",{"class":"sfazB"},"comment"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," \\"],["span",{"class":"sTEyZ"},"Relaticle"],["span",{"class":"sMK4o"},"\\"],["span",{"class":"sTEyZ"},"Comments"],["span",{"class":"sMK4o"},"\\"],["span",{"class":"sBMFI"},"Comment"],["span",{"class":"sMK4o"},"::"],["span",{"class":"sbssI"},"class"],["span",{"class":"sMK4o"},",\n"]],["span",{"class":"line","line":3},["span",{"class":"sMK4o"},"],\n"]],["span",{"class":"line","line":4},["span",{"emptyLinePlaceholder":true},"\n"]],["span",{"class":"line","line":5},["span",{"class":"sMK4o"},"'"],["span",{"class":"sfazB"},"commenter"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," [\n"]],["span",{"class":"line","line":6},["span",{"class":"sMK4o"},"    '"],["span",{"class":"sfazB"},"model"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," \\"],["span",{"class":"sTEyZ"},"App"],["span",{"class":"sMK4o"},"\\"],["span",{"class":"sTEyZ"},"Models"],["span",{"class":"sMK4o"},"\\"],["span",{"class":"sBMFI"},"User"],["span",{"class":"sMK4o"},"::"],["span",{"class":"sbssI"},"class"],["span",{"class":"sMK4o"},",\n"]],["span",{"class":"line","line":7},["span",{"class":"sMK4o"},"],\n"]]]],["p",{},"Override the Comment model to add custom behavior. The commenter model defines which class represents the user who comments."],["h2",{"id":"policy"},"Policy"],["pre",{"className":"language-php shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","code":"'policy' => \\Relaticle\\Comments\\Policies\\CommentPolicy::class,\n","language":"php","meta":"","style":""},["code",{"__ignoreMap":""},["span",{"class":"line","line":1},["span",{"class":"sMK4o"},"'"],["span",{"class":"sfazB"},"policy"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," \\"],["span",{"class":"sTEyZ"},"Relaticle"],["span",{"class":"sMK4o"},"\\"],["span",{"class":"sTEyZ"},"Comments"],["span",{"class":"sMK4o"},"\\"],["span",{"class":"sTEyZ"},"Policies"],["span",{"class":"sMK4o"},"\\"],["span",{"class":"sBMFI"},"CommentPolicy"],["span",{"class":"sMK4o"},"::"],["span",{"class":"sbssI"},"class"],["span",{"class":"sMK4o"},",\n"]]]],["p",{},"See the ",["a",{"href":"/essentials/authorization"},"Authorization"]," page for customization details."],["h2",{"id":"threading"},"Threading"],["pre",{"className":"language-php shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","code":"'threading' => [\n    'max_depth' => 2,\n],\n","language":"php","meta":"","style":""},["code",{"__ignoreMap":""},["span",{"class":"line","line":1},["span",{"class":"sMK4o"},"'"],["span",{"class":"sfazB"},"threading"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," [\n"]],["span",{"class":"line","line":2},["span",{"class":"sMK4o"},"    '"],["span",{"class":"sfazB"},"max_depth"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sbssI"}," 2"],["span",{"class":"sMK4o"},",\n"]],["span",{"class":"line","line":3},["span",{"class":"sMK4o"},"],\n"]]]],["p",{},"Controls how many levels of nested replies are allowed. A depth of ",["code",{},"2"]," means top-level comments and one level of replies. Set to ",["code",{},"1"]," to disable replies entirely."],["h2",{"id":"pagination"},"Pagination"],["pre",{"className":"language-php shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","code":"'pagination' => [\n    'per_page' => 10,\n],\n","language":"php","meta":"","style":""},["code",{"__ignoreMap":""},["span",{"class":"line","line":1},["span",{"class":"sMK4o"},"'"],["span",{"class":"sfazB"},"pagination"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," [\n"]],["span",{"class":"line","line":2},["span",{"class":"sMK4o"},"    '"],["span",{"class":"sfazB"},"per_page"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sbssI"}," 10"],["span",{"class":"sMK4o"},",\n"]],["span",{"class":"line","line":3},["span",{"class":"sMK4o"},"],\n"]]]],["p",{},"Number of comments loaded initially and per \"Load More\" click."],["h2",{"id":"reactions"},"Reactions"],["pre",{"className":"language-php shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","code":"'reactions' => [\n    'emoji_set' => [\n        'thumbs_up' => \"\\u{1F44D}\",\n        'heart' => \"\\u{2764}\\u{FE0F}\",\n        'celebrate' => \"\\u{1F389}\",\n        'laugh' => \"\\u{1F604}\",\n        'thinking' => \"\\u{1F914}\",\n        'sad' => \"\\u{1F622}\",\n    ],\n],\n","language":"php","meta":"","style":""},["code",{"__ignoreMap":""},["span",{"class":"line","line":1},["span",{"class":"sMK4o"},"'"],["span",{"class":"sfazB"},"reactions"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," [\n"]],["span",{"class":"line","line":2},["span",{"class":"sMK4o"},"    '"],["span",{"class":"sfazB"},"emoji_set"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," [\n"]],["span",{"class":"line","line":3},["span",{"class":"sMK4o"},"        '"],["span",{"class":"sfazB"},"thumbs_up"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," \""],["span",{"class":"sTEyZ"},"\\u{1F44D}"],["span",{"class":"sMK4o"},"\""],["span",{"class":"sMK4o"},",\n"]],["span",{"class":"line","line":4},["span",{"class":"sMK4o"},"        '"],["span",{"class":"sfazB"},"heart"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," \""],["span",{"class":"sTEyZ"},"\\u{2764}\\u{FE0F}"],["span",{"class":"sMK4o"},"\""],["span",{"class":"sMK4o"},",\n"]],["span",{"class":"line","line":5},["span",{"class":"sMK4o"},"        '"],["span",{"class":"sfazB"},"celebrate"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," \""],["span",{"class":"sTEyZ"},"\\u{1F389}"],["span",{"class":"sMK4o"},"\""],["span",{"class":"sMK4o"},",\n"]],["span",{"class":"line","line":6},["span",{"class":"sMK4o"},"        '"],["span",{"class":"sfazB"},"laugh"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," \""],["span",{"class":"sTEyZ"},"\\u{1F604}"],["span",{"class":"sMK4o"},"\""],["span",{"class":"sMK4o"},",\n"]],["span",{"class":"line","line":7},["span",{"class":"sMK4o"},"        '"],["span",{"class":"sfazB"},"thinking"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," \""],["span",{"class":"sTEyZ"},"\\u{1F914}"],["span",{"class":"sMK4o"},"\""],["span",{"class":"sMK4o"},",\n"]],["span",{"class":"line","line":8},["span",{"class":"sMK4o"},"        '"],["span",{"class":"sfazB"},"sad"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," \""],["span",{"class":"sTEyZ"},"\\u{1F622}"],["span",{"class":"sMK4o"},"\""],["span",{"class":"sMK4o"},",\n"]],["span",{"class":"line","line":9},["span",{"class":"sMK4o"},"    ],\n"]],["span",{"class":"line","line":10},["span",{"class":"sMK4o"},"],\n"]]]],["p",{},"Customize the available emoji reactions. Keys are used as identifiers in the database, values are the displayed emoji characters."],["h2",{"id":"mentions"},"Mentions"],["pre",{"className":"language-php shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","code":"'mentions' => [\n    'resolver' => \\Relaticle\\Comments\\Mentions\\DefaultMentionResolver::class,\n    'max_results' => 5,\n],\n","language":"php","meta":"","style":""},["code",{"__ignoreMap":""},["span",{"class":"line","line":1},["span",{"class":"sMK4o"},"'"],["span",{"class":"sfazB"},"mentions"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," [\n"]],["span",{"class":"line","line":2},["span",{"class":"sMK4o"},"    '"],["span",{"class":"sfazB"},"resolver"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," \\"],["span",{"class":"sTEyZ"},"Relaticle"],["span",{"class":"sMK4o"},"\\"],["span",{"class":"sTEyZ"},"Comments"],["span",{"class":"sMK4o"},"\\"],["span",{"class":"sTEyZ"},"Mentions"],["span",{"class":"sMK4o"},"\\"],["span",{"class":"sBMFI"},"DefaultMentionResolver"],["span",{"class":"sMK4o"},"::"],["span",{"class":"sbssI"},"class"],["span",{"class":"sMK4o"},",\n"]],["span",{"class":"line","line":3},["span",{"class":"sMK4o"},"    '"],["span",{"class":"sfazB"},"max_results"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sbssI"}," 5"],["span",{"class":"sMK4o"},",\n"]],["span",{"class":"line","line":4},["span",{"class":"sMK4o"},"],\n"]]]],["p",{},"The resolver handles searching for users during @mention autocomplete. See the ",["a",{"href":"/essentials/mentions"},"Mentions"]," page for creating a custom resolver."],["h2",{"id":"editor-toolbar"},"Editor Toolbar"],["pre",{"className":"language-php shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","code":"'editor' => [\n    'toolbar' => [\n        ['bold', 'italic', 'strike', 'link'],\n        ['bulletList', 'orderedList'],\n        ['codeBlock'],\n    ],\n],\n","language":"php","meta":"","style":""},["code",{"__ignoreMap":""},["span",{"class":"line","line":1},["span",{"class":"sMK4o"},"'"],["span",{"class":"sfazB"},"editor"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," [\n"]],["span",{"class":"line","line":2},["span",{"class":"sMK4o"},"    '"],["span",{"class":"sfazB"},"toolbar"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," [\n"]],["span",{"class":"line","line":3},["span",{"class":"sMK4o"},"        ["],["span",{"class":"sMK4o"},"'"],["span",{"class":"sfazB"},"bold"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"},","],["span",{"class":"sMK4o"}," '"],["span",{"class":"sfazB"},"italic"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"},","],["span",{"class":"sMK4o"}," '"],["span",{"class":"sfazB"},"strike"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"},","],["span",{"class":"sMK4o"}," '"],["span",{"class":"sfazB"},"link"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"},"],\n"]],["span",{"class":"line","line":4},["span",{"class":"sMK4o"},"        ["],["span",{"class":"sMK4o"},"'"],["span",{"class":"sfazB"},"bulletList"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"},","],["span",{"class":"sMK4o"}," '"],["span",{"class":"sfazB"},"orderedList"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"},"],\n"]],["span",{"class":"line","line":5},["span",{"class":"sMK4o"},"        ["],["span",{"class":"sMK4o"},"'"],["span",{"class":"sfazB"},"codeBlock"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"},"],\n"]],["span",{"class":"line","line":6},["span",{"class":"sMK4o"},"    ],\n"]],["span",{"class":"line","line":7},["span",{"class":"sMK4o"},"],\n"]]]],["p",{},"Defines which formatting buttons appear in the comment editor. Groups create visual separators in the toolbar."],["h2",{"id":"notifications"},"Notifications"],["pre",{"className":"language-php shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","code":"'notifications' => [\n    'channels' => ['database'],\n    'enabled' => true,\n],\n","language":"php","meta":"","style":""},["code",{"__ignoreMap":""},["span",{"class":"line","line":1},["span",{"class":"sMK4o"},"'"],["span",{"class":"sfazB"},"notifications"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," [\n"]],["span",{"class":"line","line":2},["span",{"class":"sMK4o"},"    '"],["span",{"class":"sfazB"},"channels"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," ["],["span",{"class":"sMK4o"},"'"],["span",{"class":"sfazB"},"database"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"},"],\n"]],["span",{"class":"line","line":3},["span",{"class":"sMK4o"},"    '"],["span",{"class":"sfazB"},"enabled"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," true,\n"]],["span",{"class":"line","line":4},["span",{"class":"sMK4o"},"],\n"]]]],["p",{},"Add ",["code",{},"'mail'"]," to the channels array to send email notifications. Set ",["code",{},"enabled"]," to ",["code",{},"false"]," to disable all notifications."],["h2",{"id":"subscriptions"},"Subscriptions"],["pre",{"className":"language-php shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","code":"'subscriptions' => [\n    'auto_subscribe' => true,\n],\n","language":"php","meta":"","style":""},["code",{"__ignoreMap":""},["span",{"class":"line","line":1},["span",{"class":"sMK4o"},"'"],["span",{"class":"sfazB"},"subscriptions"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," [\n"]],["span",{"class":"line","line":2},["span",{"class":"sMK4o"},"    '"],["span",{"class":"sfazB"},"auto_subscribe"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," true,\n"]],["span",{"class":"line","line":3},["span",{"class":"sMK4o"},"],\n"]]]],["p",{},"When enabled, users are automatically subscribed to a thread when they create a comment or are mentioned. They receive notifications for subsequent replies."],["h2",{"id":"attachments"},"Attachments"],["pre",{"className":"language-php shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","code":"'attachments' => [\n    'enabled' => true,\n    'disk' => 'public',\n    'max_size' => 10240, // KB\n    'allowed_types' => [\n        'image/jpeg',\n        'image/png',\n        'image/gif',\n        'image/webp',\n        'application/pdf',\n        'text/plain',\n        'application/msword',\n        'application/vnd.openxmlformats-officedocument.wordprocessingml.document',\n    ],\n],\n","language":"php","meta":"","style":""},["code",{"__ignoreMap":""},["span",{"class":"line","line":1},["span",{"class":"sMK4o"},"'"],["span",{"class":"sfazB"},"attachments"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," [\n"]],["span",{"class":"line","line":2},["span",{"class":"sMK4o"},"    '"],["span",{"class":"sfazB"},"enabled"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," true,\n"]],["span",{"class":"line","line":3},["span",{"class":"sMK4o"},"    '"],["span",{"class":"sfazB"},"disk"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," '"],["span",{"class":"sfazB"},"public"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"},",\n"]],["span",{"class":"line","line":4},["span",{"class":"sMK4o"},"    '"],["span",{"class":"sfazB"},"max_size"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sbssI"}," 10240"],["span",{"class":"sMK4o"},","],["span",{"class":"sHwdD"}," // KB\n"]],["span",{"class":"line","line":5},["span",{"class":"sMK4o"},"    '"],["span",{"class":"sfazB"},"allowed_types"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," [\n"]],["span",{"class":"line","line":6},["span",{"class":"sMK4o"},"        '"],["span",{"class":"sfazB"},"image/jpeg"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"},",\n"]],["span",{"class":"line","line":7},["span",{"class":"sMK4o"},"        '"],["span",{"class":"sfazB"},"image/png"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"},",\n"]],["span",{"class":"line","line":8},["span",{"class":"sMK4o"},"        '"],["span",{"class":"sfazB"},"image/gif"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"},",\n"]],["span",{"class":"line","line":9},["span",{"class":"sMK4o"},"        '"],["span",{"class":"sfazB"},"image/webp"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"},",\n"]],["span",{"class":"line","line":10},["span",{"class":"sMK4o"},"        '"],["span",{"class":"sfazB"},"application/pdf"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"},",\n"]],["span",{"class":"line","line":11},["span",{"class":"sMK4o"},"        '"],["span",{"class":"sfazB"},"text/plain"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"},",\n"]],["span",{"class":"line","line":12},["span",{"class":"sMK4o"},"        '"],["span",{"class":"sfazB"},"application/msword"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"},",\n"]],["span",{"class":"line","line":13},["span",{"class":"sMK4o"},"        '"],["span",{"class":"sfazB"},"application/vnd.openxmlformats-officedocument.wordprocessingml.document"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"},",\n"]],["span",{"class":"line","line":14},["span",{"class":"sMK4o"},"    ],\n"]],["span",{"class":"line","line":15},["span",{"class":"sMK4o"},"],\n"]]]],["p",{},"Controls file upload behavior. Set ",["code",{},"enabled"]," to ",["code",{},"false"]," to remove the attachment UI entirely. The ",["code",{},"max_size"]," is in kilobytes (default 10 MB)."],["h2",{"id":"broadcasting"},"Broadcasting"],["pre",{"className":"language-php shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","code":"'broadcasting' => [\n    'enabled' => false,\n    'channel_prefix' => 'comments',\n],\n","language":"php","meta":"","style":""},["code",{"__ignoreMap":""},["span",{"class":"line","line":1},["span",{"class":"sMK4o"},"'"],["span",{"class":"sfazB"},"broadcasting"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," [\n"]],["span",{"class":"line","line":2},["span",{"class":"sMK4o"},"    '"],["span",{"class":"sfazB"},"enabled"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," false,\n"]],["span",{"class":"line","line":3},["span",{"class":"sMK4o"},"    '"],["span",{"class":"sfazB"},"channel_prefix"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," '"],["span",{"class":"sfazB"},"comments"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"},",\n"]],["span",{"class":"line","line":4},["span",{"class":"sMK4o"},"],\n"]]]],["p",{},"When enabled, comment events are broadcast on private channels using the format ",["code",{},"{prefix}.{commentable_type}.{commentable_id}"],". Requires Laravel Echo and a broadcasting driver."],["h2",{"id":"polling"},"Polling"],["pre",{"className":"language-php shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","code":"'polling' => [\n    'interval' => '10s',\n],\n","language":"php","meta":"","style":""},["code",{"__ignoreMap":""},["span",{"class":"line","line":1},["span",{"class":"sMK4o"},"'"],["span",{"class":"sfazB"},"polling"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," [\n"]],["span",{"class":"line","line":2},["span",{"class":"sMK4o"},"    '"],["span",{"class":"sfazB"},"interval"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," '"],["span",{"class":"sfazB"},"10s"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"},",\n"]],["span",{"class":"line","line":3},["span",{"class":"sMK4o"},"],\n"]]]],["p",{},"When broadcasting is disabled, the Livewire component polls for new comments at this interval. Set to ",["code",{},"null"]," to disable polling."],["h2",{"id":"custom-user-resolution"},"Custom User Resolution"],["p",{},"Override how the authenticated user is resolved:"],["pre",{"className":"language-php shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","code":"use Relaticle\\Comments\\Config;\n\n// In AppServiceProvider::boot()\nConfig::resolveAuthenticatedUserUsing(function () {\n    return auth()->user();\n});\n","language":"php","meta":"","style":""},["code",{"__ignoreMap":""},["span",{"class":"line","line":1},["span",{"class":"sbssI"},"use"],["span",{"class":"sTEyZ"}," Relaticle"],["span",{"class":"sMK4o"},"\\"],["span",{"class":"sTEyZ"},"Comments"],["span",{"class":"sMK4o"},"\\"],["span",{"class":"sTEyZ"},"Config"],["span",{"class":"sMK4o"},";\n"]],["span",{"class":"line","line":2},["span",{"emptyLinePlaceholder":true},"\n"]],["span",{"class":"line","line":3},["span",{"class":"sHwdD"},"// In AppServiceProvider::boot()\n"]],["span",{"class":"line","line":4},["span",{"class":"sBMFI"},"Config"],["span",{"class":"sMK4o"},"::"],["span",{"class":"s2Zo4"},"resolveAuthenticatedUserUsing"],["span",{"class":"sMK4o"},"("],["span",{"class":"spNyl"},"function"],["span",{"class":"sMK4o"}," ()"],["span",{"class":"sMK4o"}," {\n"]],["span",{"class":"line","line":5},["span",{"class":"s7zQu"},"    return"],["span",{"class":"s2Zo4"}," auth"],["span",{"class":"sMK4o"},"()->"],["span",{"class":"s2Zo4"},"user"],["span",{"class":"sMK4o"},"();\n"]],["span",{"class":"line","line":6},["span",{"class":"sMK4o"},"});\n"]]]],["p",{},"This is useful for multi-guard applications or custom authentication flows."],["style",{},"html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}"]],"toc":{"title":"","searchDepth":2,"depth":2,"links":[{"id":"table-name","depth":2,"text":"Table Name"},{"id":"models","depth":2,"text":"Models"},{"id":"policy","depth":2,"text":"Policy"},{"id":"threading","depth":2,"text":"Threading"},{"id":"pagination","depth":2,"text":"Pagination"},{"id":"reactions","depth":2,"text":"Reactions"},{"id":"mentions","depth":2,"text":"Mentions"},{"id":"editor-toolbar","depth":2,"text":"Editor Toolbar"},{"id":"notifications","depth":2,"text":"Notifications"},{"id":"subscriptions","depth":2,"text":"Subscriptions"},{"id":"attachments","depth":2,"text":"Attachments"},{"id":"broadcasting","depth":2,"text":"Broadcasting"},{"id":"polling","depth":2,"text":"Polling"},{"id":"custom-user-resolution","depth":2,"text":"Custom User Resolution"}]}}

seo:
{"description":"Complete configuration reference for the Comments package.","title":"Configuration"}


id: docs/2.essentials/2.authorization.md
title: Authorization
description: Control who can create, edit, delete, and reply to comments.
extension: md
meta: {}
navigation: {"icon":"i-lucide-shield"}
path: /essentials/authorization
seo: {"description":"Configure comment authorization policies.","title":"Authorization"}
stem: 2.essentials/2.authorization
__hash__: YnHyEHTZ0JhpjKoVXd3F9RBoyGiM3pyczDpn5a5Grfo
body:
{"type":"minimark","value":[["h2",{"id":"default-policy"},"Default Policy"],["p",{},"The built-in ",["code",{},"CommentPolicy"]," provides sensible defaults:"],["table",{},["thead",{},["tr",{},["th",{},"Method"],["th",{},"Default"],["th",{},"Description"]]],["tbody",{},["tr",{},["td",{},["code",{},"viewAny()"]],["td",{},["code",{},"true"]],["td",{},"Everyone can view comments"]],["tr",{},["td",{},["code",{},"create()"]],["td",{},["code",{},"true"]],["td",{},"Everyone can create comments"]],["tr",{},["td",{},["code",{},"update()"]],["td",{},"Owner only"],["td",{},"Only the comment author can edit"]],["tr",{},["td",{},["code",{},"delete()"]],["td",{},"Owner only"],["td",{},"Only the comment author can delete"]],["tr",{},["td",{},["code",{},"reply()"]],["td",{},"Depth check"],["td",{},"Can reply if ",["code",{},"max_depth"]," not exceeded"]]]],["h2",{"id":"custom-policy"},"Custom Policy"],["p",{},"Create your own policy to customize authorization:"],["pre",{"className":"language-php shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","code":"namespace App\\Policies;\n\nuse Relaticle\\Comments\\Comment;\nuse Relaticle\\Comments\\Contracts\\Commenter;\n\nclass CustomCommentPolicy\n{\n    public function viewAny(Commenter $user): bool\n    {\n        return true;\n    }\n\n    public function create(Commenter $user): bool\n    {\n        return true;\n    }\n\n    public function update(Commenter $user, Comment $comment): bool\n    {\n        return $comment->user_id === $user->getKey()\n            && $comment->user_type === $user->getMorphClass();\n    }\n\n    public function delete(Commenter $user, Comment $comment): bool\n    {\n        return $comment->user_id === $user->getKey()\n            || $user->hasRole('admin');\n    }\n\n    public function reply(Commenter $user, Comment $comment): bool\n    {\n        return $comment->canReply();\n    }\n}\n","language":"php","meta":"","style":""},["code",{"__ignoreMap":""},["span",{"class":"line","line":1},["span",{"class":"sbssI"},"namespace"],["span",{"class":"sBMFI"}," App"],["span",{"class":"sMK4o"},"\\"],["span",{"class":"sBMFI"},"Policies"],["span",{"class":"sMK4o"},";\n"]],["span",{"class":"line","line":2},["span",{"emptyLinePlaceholder":true},"\n"]],["span",{"class":"line","line":3},["span",{"class":"sbssI"},"use"],["span",{"class":"sTEyZ"}," Relaticle"],["span",{"class":"sMK4o"},"\\"],["span",{"class":"sTEyZ"},"Comments"],["span",{"class":"sMK4o"},"\\"],["span",{"class":"sTEyZ"},"Comment"],["span",{"class":"sMK4o"},";\n"]],["span",{"class":"line","line":4},["span",{"class":"sbssI"},"use"],["span",{"class":"sTEyZ"}," Relaticle"],["span",{"class":"sMK4o"},"\\"],["span",{"class":"sTEyZ"},"Comments"],["span",{"class":"sMK4o"},"\\"],["span",{"class":"sTEyZ"},"Contracts"],["span",{"class":"sMK4o"},"\\"],["span",{"class":"sTEyZ"},"Commenter"],["span",{"class":"sMK4o"},";\n"]],["span",{"class":"line","line":5},["span",{"emptyLinePlaceholder":true},"\n"]],["span",{"class":"line","line":6},["span",{"class":"spNyl"},"class"],["span",{"class":"sBMFI"}," CustomCommentPolicy\n"]],["span",{"class":"line","line":7},["span",{"class":"sMK4o"},"{\n"]],["span",{"class":"line","line":8},["span",{"class":"spNyl"},"    public"],["span",{"class":"spNyl"}," function"],["span",{"class":"s2Zo4"}," viewAny"],["span",{"class":"sMK4o"},"("],["span",{"class":"sBMFI"},"Commenter"],["span",{"class":"sMK4o"}," $"],["span",{"class":"sTEyZ"},"user"],["span",{"class":"sMK4o"},"):"],["span",{"class":"sbssI"}," bool\n"]],["span",{"class":"line","line":9},["span",{"class":"sMK4o"},"    {\n"]],["span",{"class":"line","line":10},["span",{"class":"s7zQu"},"        return"],["span",{"class":"sMK4o"}," true;\n"]],["span",{"class":"line","line":11},["span",{"class":"sMK4o"},"    }\n"]],["span",{"class":"line","line":12},["span",{"emptyLinePlaceholder":true},"\n"]],["span",{"class":"line","line":13},["span",{"class":"spNyl"},"    public"],["span",{"class":"spNyl"}," function"],["span",{"class":"s2Zo4"}," create"],["span",{"class":"sMK4o"},"("],["span",{"class":"sBMFI"},"Commenter"],["span",{"class":"sMK4o"}," $"],["span",{"class":"sTEyZ"},"user"],["span",{"class":"sMK4o"},"):"],["span",{"class":"sbssI"}," bool\n"]],["span",{"class":"line","line":14},["span",{"class":"sMK4o"},"    {\n"]],["span",{"class":"line","line":15},["span",{"class":"s7zQu"},"        return"],["span",{"class":"sMK4o"}," true;\n"]],["span",{"class":"line","line":16},["span",{"class":"sMK4o"},"    }\n"]],["span",{"class":"line","line":17},["span",{"emptyLinePlaceholder":true},"\n"]],["span",{"class":"line","line":18},["span",{"class":"spNyl"},"    public"],["span",{"class":"spNyl"}," function"],["span",{"class":"s2Zo4"}," update"],["span",{"class":"sMK4o"},"("],["span",{"class":"sBMFI"},"Commenter"],["span",{"class":"sMK4o"}," $"],["span",{"class":"sTEyZ"},"user"],["span",{"class":"sMK4o"},","],["span",{"class":"sBMFI"}," Comment"],["span",{"class":"sMK4o"}," $"],["span",{"class":"sTEyZ"},"comment"],["span",{"class":"sMK4o"},"):"],["span",{"class":"sbssI"}," bool\n"]],["span",{"class":"line","line":19},["span",{"class":"sMK4o"},"    {\n"]],["span",{"class":"line","line":20},["span",{"class":"s7zQu"},"        return"],["span",{"class":"sMK4o"}," $"],["span",{"class":"sTEyZ"},"comment"],["span",{"class":"sMK4o"},"->"],["span",{"class":"sTEyZ"},"user_id "],["span",{"class":"sMK4o"},"==="],["span",{"class":"sMK4o"}," $"],["span",{"class":"sTEyZ"},"user"],["span",{"class":"sMK4o"},"->"],["span",{"class":"s2Zo4"},"getKey"],["span",{"class":"sMK4o"},"()\n"]],["span",{"class":"line","line":21},["span",{"class":"sMK4o"},"            &&"],["span",{"class":"sMK4o"}," $"],["span",{"class":"sTEyZ"},"comment"],["span",{"class":"sMK4o"},"->"],["span",{"class":"sTEyZ"},"user_type "],["span",{"class":"sMK4o"},"==="],["span",{"class":"sMK4o"}," $"],["span",{"class":"sTEyZ"},"user"],["span",{"class":"sMK4o"},"->"],["span",{"class":"s2Zo4"},"getMorphClass"],["span",{"class":"sMK4o"},"();\n"]],["span",{"class":"line","line":22},["span",{"class":"sMK4o"},"    }\n"]],["span",{"class":"line","line":23},["span",{"emptyLinePlaceholder":true},"\n"]],["span",{"class":"line","line":24},["span",{"class":"spNyl"},"    public"],["span",{"class":"spNyl"}," function"],["span",{"class":"s2Zo4"}," delete"],["span",{"class":"sMK4o"},"("],["span",{"class":"sBMFI"},"Commenter"],["span",{"class":"sMK4o"}," $"],["span",{"class":"sTEyZ"},"user"],["span",{"class":"sMK4o"},","],["span",{"class":"sBMFI"}," Comment"],["span",{"class":"sMK4o"}," $"],["span",{"class":"sTEyZ"},"comment"],["span",{"class":"sMK4o"},"):"],["span",{"class":"sbssI"}," bool\n"]],["span",{"class":"line","line":25},["span",{"class":"sMK4o"},"    {\n"]],["span",{"class":"line","line":26},["span",{"class":"s7zQu"},"        return"],["span",{"class":"sMK4o"}," $"],["span",{"class":"sTEyZ"},"comment"],["span",{"class":"sMK4o"},"->"],["span",{"class":"sTEyZ"},"user_id "],["span",{"class":"sMK4o"},"==="],["span",{"class":"sMK4o"}," $"],["span",{"class":"sTEyZ"},"user"],["span",{"class":"sMK4o"},"->"],["span",{"class":"s2Zo4"},"getKey"],["span",{"class":"sMK4o"},"()\n"]],["span",{"class":"line","line":27},["span",{"class":"sMK4o"},"            ||"],["span",{"class":"sMK4o"}," $"],["span",{"class":"sTEyZ"},"user"],["span",{"class":"sMK4o"},"->"],["span",{"class":"s2Zo4"},"hasRole"],["span",{"class":"sMK4o"},"("],["span",{"class":"sMK4o"},"'"],["span",{"class":"sfazB"},"admin"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"},");\n"]],["span",{"class":"line","line":28},["span",{"class":"sMK4o"},"    }\n"]],["span",{"class":"line","line":29},["span",{"emptyLinePlaceholder":true},"\n"]],["span",{"class":"line","line":30},["span",{"class":"spNyl"},"    public"],["span",{"class":"spNyl"}," function"],["span",{"class":"s2Zo4"}," reply"],["span",{"class":"sMK4o"},"("],["span",{"class":"sBMFI"},"Commenter"],["span",{"class":"sMK4o"}," $"],["span",{"class":"sTEyZ"},"user"],["span",{"class":"sMK4o"},","],["span",{"class":"sBMFI"}," Comment"],["span",{"class":"sMK4o"}," $"],["span",{"class":"sTEyZ"},"comment"],["span",{"class":"sMK4o"},"):"],["span",{"class":"sbssI"}," bool\n"]],["span",{"class":"line","line":31},["span",{"class":"sMK4o"},"    {\n"]],["span",{"class":"line","line":32},["span",{"class":"s7zQu"},"        return"],["span",{"class":"sMK4o"}," $"],["span",{"class":"sTEyZ"},"comment"],["span",{"class":"sMK4o"},"->"],["span",{"class":"s2Zo4"},"canReply"],["span",{"class":"sMK4o"},"();\n"]],["span",{"class":"line","line":33},["span",{"class":"sMK4o"},"    }\n"]],["span",{"class":"line","line":34},["span",{"class":"sMK4o"},"}\n"]]]],["p",{},"Register it in your config:"],["pre",{"className":"language-php shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","code":"// config/comments.php\n'policy' => App\\Policies\\CustomCommentPolicy::class,\n","language":"php","meta":"","style":""},["code",{"__ignoreMap":""},["span",{"class":"line","line":1},["span",{"class":"sHwdD"},"// config/comments.php\n"]],["span",{"class":"line","line":2},["span",{"class":"sMK4o"},"'"],["span",{"class":"sfazB"},"policy"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sTEyZ"}," App"],["span",{"class":"sMK4o"},"\\"],["span",{"class":"sTEyZ"},"Policies"],["span",{"class":"sMK4o"},"\\"],["span",{"class":"sBMFI"},"CustomCommentPolicy"],["span",{"class":"sMK4o"},"::"],["span",{"class":"sbssI"},"class"],["span",{"class":"sMK4o"},",\n"]]]],["h2",{"id":"how-authorization-works"},"How Authorization Works"],["p",{},"The Livewire components check the policy before rendering action buttons. Edit and delete buttons only appear for authorized users. Reply buttons are hidden when the thread has reached the configured ",["code",{},"max_depth"],"."],["p",{},"The policy is registered automatically by the service provider using Laravel's Gate system."],["style",{},"html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}"]],"toc":{"title":"","searchDepth":2,"depth":2,"links":[{"id":"default-policy","depth":2,"text":"Default Policy"},{"id":"custom-policy","depth":2,"text":"Custom Policy"},{"id":"how-authorization-works","depth":2,"text":"How Authorization Works"}]}}


id: docs/2.essentials/3.mentions.md
title: Mentions
description: User @mentions with autocomplete and notification support.
extension: md
meta: {}
navigation: {"icon":"i-lucide-at-sign"}
path: /essentials/mentions
stem: 2.essentials/3.mentions
__hash__: kQQwvRy9HYB1t8O3MnVh58m8bi_XmvTWpYWrdhjepK8
body:
{"type":"minimark","value":[["h2",{"id":"how-mentions-work"},"How Mentions Work"],["p",{},"Type ",["code",{},"@"]," in the comment editor to trigger user autocomplete. Select a user to insert a mention. When the comment is saved, the ",["code",{},"MentionParser"]," extracts mentions and:"],["ol",{},["li",{},"Syncs mention records in the ",["code",{},"comment_mentions"]," table"],["li",{},"Dispatches a ",["code",{},"UserMentioned"]," event for each newly mentioned user"],["li",{},"The ",["code",{},"SendUserMentionedNotification"]," listener sends notifications"],["li",{},"If auto-subscribe is enabled, mentioned users are subscribed to the thread"]],["h2",{"id":"default-resolver"},"Default Resolver"],["p",{},"The ",["code",{},"DefaultMentionResolver"]," searches the commenter model by name:"],["pre",{"className":"language-php shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","code":"// Searches: User::where('name', 'like', \"{$query}%\")\n// Limited to: config('comments.mentions.max_results') results\n","language":"php","meta":"","style":""},["code",{"__ignoreMap":""},["span",{"class":"line","line":1},["span",{"class":"sHwdD"},"// Searches: User::where('name', 'like', \"{$query}%\")\n"]],["span",{"class":"line","line":2},["span",{"class":"sHwdD"},"// Limited to: config('comments.mentions.max_results') results\n"]]]],["h2",{"id":"custom-mention-resolver"},"Custom Mention Resolver"],["p",{},"Implement the ",["code",{},"MentionResolver"]," interface to customize user search behavior:"],["pre",{"className":"language-php shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","code":"namespace App\\Comments;\n\nuse Illuminate\\Support\\Collection;\nuse Relaticle\\Comments\\Contracts\\MentionResolver;\n\nclass TeamMentionResolver implements MentionResolver\n{\n    public function search(string $query): Collection\n    {\n        return User::query()\n            ->where('team_id', auth()->user()->team_id)\n            ->where('name', 'like', \"{$query}%\")\n            ->limit(config('comments.mentions.max_results'))\n            ->get();\n    }\n\n    public function resolveByNames(array $names): Collection\n    {\n        return User::query()\n            ->where('team_id', auth()->user()->team_id)\n            ->whereIn('name', $names)\n            ->get();\n    }\n}\n","language":"php","meta":"","style":""},["code",{"__ignoreMap":""},["span",{"class":"line","line":1},["span",{"class":"sbssI"},"namespace"],["span",{"class":"sBMFI"}," App"],["span",{"class":"sMK4o"},"\\"],["span",{"class":"sBMFI"},"Comments"],["span",{"class":"sMK4o"},";\n"]],["span",{"class":"line","line":2},["span",{"emptyLinePlaceholder":true},"\n"]],["span",{"class":"line","line":3},["span",{"class":"sbssI"},"use"],["span",{"class":"sTEyZ"}," Illuminate"],["span",{"class":"sMK4o"},"\\"],["span",{"class":"sTEyZ"},"Support"],["span",{"class":"sMK4o"},"\\"],["span",{"class":"sTEyZ"},"Collection"],["span",{"class":"sMK4o"},";\n"]],["span",{"class":"line","line":4},["span",{"class":"sbssI"},"use"],["span",{"class":"sTEyZ"}," Relaticle"],["span",{"class":"sMK4o"},"\\"],["span",{"class":"sTEyZ"},"Comments"],["span",{"class":"sMK4o"},"\\"],["span",{"class":"sTEyZ"},"Contracts"],["span",{"class":"sMK4o"},"\\"],["span",{"class":"sTEyZ"},"MentionResolver"],["span",{"class":"sMK4o"},";\n"]],["span",{"class":"line","line":5},["span",{"emptyLinePlaceholder":true},"\n"]],["span",{"class":"line","line":6},["span",{"class":"spNyl"},"class"],["span",{"class":"sBMFI"}," TeamMentionResolver"],["span",{"class":"spNyl"}," implements"],["span",{"class":"sBMFI"}," MentionResolver\n"]],["span",{"class":"line","line":7},["span",{"class":"sMK4o"},"{\n"]],["span",{"class":"line","line":8},["span",{"class":"spNyl"},"    public"],["span",{"class":"spNyl"}," function"],["span",{"class":"s2Zo4"}," search"],["span",{"class":"sMK4o"},"("],["span",{"class":"sbssI"},"string"],["span",{"class":"sMK4o"}," $"],["span",{"class":"sTEyZ"},"query"],["span",{"class":"sMK4o"},"):"],["span",{"class":"sBMFI"}," Collection\n"]],["span",{"class":"line","line":9},["span",{"class":"sMK4o"},"    {\n"]],["span",{"class":"line","line":10},["span",{"class":"s7zQu"},"        return"],["span",{"class":"sBMFI"}," User"],["span",{"class":"sMK4o"},"::"],["span",{"class":"s2Zo4"},"query"],["span",{"class":"sMK4o"},"()\n"]],["span",{"class":"line","line":11},["span",{"class":"sMK4o"},"            ->"],["span",{"class":"s2Zo4"},"where"],["span",{"class":"sMK4o"},"("],["span",{"class":"sMK4o"},"'"],["span",{"class":"sfazB"},"team_id"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"},","],["span",{"class":"s2Zo4"}," auth"],["span",{"class":"sMK4o"},"()->"],["span",{"class":"s2Zo4"},"user"],["span",{"class":"sMK4o"},"()->"],["span",{"class":"sTEyZ"},"team_id"],["span",{"class":"sMK4o"},")\n"]],["span",{"class":"line","line":12},["span",{"class":"sMK4o"},"            ->"],["span",{"class":"s2Zo4"},"where"],["span",{"class":"sMK4o"},"("],["span",{"class":"sMK4o"},"'"],["span",{"class":"sfazB"},"name"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"},","],["span",{"class":"sMK4o"}," '"],["span",{"class":"sfazB"},"like"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"},","],["span",{"class":"sMK4o"}," \"{$"],["span",{"class":"sTEyZ"},"query"],["span",{"class":"sMK4o"},"}"],["span",{"class":"sfazB"},"%"],["span",{"class":"sMK4o"},"\""],["span",{"class":"sMK4o"},")\n"]],["span",{"class":"line","line":13},["span",{"class":"sMK4o"},"            ->"],["span",{"class":"s2Zo4"},"limit"],["span",{"class":"sMK4o"},"("],["span",{"class":"s2Zo4"},"config"],["span",{"class":"sMK4o"},"("],["span",{"class":"sMK4o"},"'"],["span",{"class":"sfazB"},"comments.mentions.max_results"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"},"))\n"]],["span",{"class":"line","line":14},["span",{"class":"sMK4o"},"            ->"],["span",{"class":"s2Zo4"},"get"],["span",{"class":"sMK4o"},"();\n"]],["span",{"class":"line","line":15},["span",{"class":"sMK4o"},"    }\n"]],["span",{"class":"line","line":16},["span",{"emptyLinePlaceholder":true},"\n"]],["span",{"class":"line","line":17},["span",{"class":"spNyl"},"    public"],["span",{"class":"spNyl"}," function"],["span",{"class":"s2Zo4"}," resolveByNames"],["span",{"class":"sMK4o"},"("],["span",{"class":"sbssI"},"array"],["span",{"class":"sMK4o"}," $"],["span",{"class":"sTEyZ"},"names"],["span",{"class":"sMK4o"},"):"],["span",{"class":"sBMFI"}," Collection\n"]],["span",{"class":"line","line":18},["span",{"class":"sMK4o"},"    {\n"]],["span",{"class":"line","line":19},["span",{"class":"s7zQu"},"        return"],["span",{"class":"sBMFI"}," User"],["span",{"class":"sMK4o"},"::"],["span",{"class":"s2Zo4"},"query"],["span",{"class":"sMK4o"},"()\n"]],["span",{"class":"line","line":20},["span",{"class":"sMK4o"},"            ->"],["span",{"class":"s2Zo4"},"where"],["span",{"class":"sMK4o"},"("],["span",{"class":"sMK4o"},"'"],["span",{"class":"sfazB"},"team_id"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"},","],["span",{"class":"s2Zo4"}," auth"],["span",{"class":"sMK4o"},"()->"],["span",{"class":"s2Zo4"},"user"],["span",{"class":"sMK4o"},"()->"],["span",{"class":"sTEyZ"},"team_id"],["span",{"class":"sMK4o"},")\n"]],["span",{"class":"line","line":21},["span",{"class":"sMK4o"},"            ->"],["span",{"class":"s2Zo4"},"whereIn"],["span",{"class":"sMK4o"},"("],["span",{"class":"sMK4o"},"'"],["span",{"class":"sfazB"},"name"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"},","],["span",{"class":"sMK4o"}," $"],["span",{"class":"sTEyZ"},"names"],["span",{"class":"sMK4o"},")\n"]],["span",{"class":"line","line":22},["span",{"class":"sMK4o"},"            ->"],["span",{"class":"s2Zo4"},"get"],["span",{"class":"sMK4o"},"();\n"]],["span",{"class":"line","line":23},["span",{"class":"sMK4o"},"    }\n"]],["span",{"class":"line","line":24},["span",{"class":"sMK4o"},"}\n"]]]],["p",{},"Register it in your config:"],["pre",{"className":"language-php shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","code":"// config/comments.php\n'mentions' => [\n    'resolver' => App\\Comments\\TeamMentionResolver::class,\n    'max_results' => 5,\n],\n","language":"php","meta":"","style":""},["code",{"__ignoreMap":""},["span",{"class":"line","line":1},["span",{"class":"sHwdD"},"// config/comments.php\n"]],["span",{"class":"line","line":2},["span",{"class":"sMK4o"},"'"],["span",{"class":"sfazB"},"mentions"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," [\n"]],["span",{"class":"line","line":3},["span",{"class":"sMK4o"},"    '"],["span",{"class":"sfazB"},"resolver"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sTEyZ"}," App"],["span",{"class":"sMK4o"},"\\"],["span",{"class":"sTEyZ"},"Comments"],["span",{"class":"sMK4o"},"\\"],["span",{"class":"sBMFI"},"TeamMentionResolver"],["span",{"class":"sMK4o"},"::"],["span",{"class":"sbssI"},"class"],["span",{"class":"sMK4o"},",\n"]],["span",{"class":"line","line":4},["span",{"class":"sMK4o"},"    '"],["span",{"class":"sfazB"},"max_results"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sbssI"}," 5"],["span",{"class":"sMK4o"},",\n"]],["span",{"class":"line","line":5},["span",{"class":"sMK4o"},"],\n"]]]],["h2",{"id":"configuration"},"Configuration"],["table",{},["thead",{},["tr",{},["th",{},"Key"],["th",{},"Default"],["th",{},"Description"]]],["tbody",{},["tr",{},["td",{},["code",{},"mentions.resolver"]],["td",{},["code",{},"DefaultMentionResolver::class"]],["td",{},"User search implementation"]],["tr",{},["td",{},["code",{},"mentions.max_results"]],["td",{},["code",{},"5"]],["td",{},"Maximum autocomplete results"]]]],["style",{},"html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}"]],"toc":{"title":"","searchDepth":2,"depth":2,"links":[{"id":"how-mentions-work","depth":2,"text":"How Mentions Work"},{"id":"default-resolver","depth":2,"text":"Default Resolver"},{"id":"custom-mention-resolver","depth":2,"text":"Custom Mention Resolver"},{"id":"configuration","depth":2,"text":"Configuration"}]}}

seo:
{"description":"Configure @mention autocomplete and create custom mention resolvers.","title":"Mentions"}


id: docs/2.essentials/4.reactions.md
title: Reactions
description: Emoji reactions on comments.
extension: md
meta: {}
navigation: {"icon":"i-lucide-smile"}
path: /essentials/reactions
seo: {"description":"Configure emoji reactions for comments.","title":"Reactions"}
stem: 2.essentials/4.reactions
__hash__: khYPp6eC0edZfAruTrAlDJPdOG0ElBC05t8LgYgsdSY
body:
{"type":"minimark","value":[["h2",{"id":"default-reactions"},"Default Reactions"],["p",{},"Six emoji reactions are available out of the box:"],["table",{},["thead",{},["tr",{},["th",{},"Key"],["th",{},"Emoji"],["th",{},"Label"]]],["tbody",{},["tr",{},["td",{},["code",{},"thumbs_up"]],["td",{},":thumbsup:"],["td",{},"Like"]],["tr",{},["td",{},["code",{},"heart"]],["td",{},"❤️"],["td",{},"Love"]],["tr",{},["td",{},["code",{},"celebrate"]],["td",{},"🎉"],["td",{},"Celebrate"]],["tr",{},["td",{},["code",{},"laugh"]],["td",{},"😄"],["td",{},"Laugh"]],["tr",{},["td",{},["code",{},"thinking"]],["td",{},"🤔"],["td",{},"Thinking"]],["tr",{},["td",{},["code",{},"sad"]],["td",{},"😢"],["td",{},"Sad"]]]],["h2",{"id":"how-reactions-work"},"How Reactions Work"],["ul",{},["li",{},"Each user can add one reaction of each type per comment"],["li",{},"Clicking the same reaction again removes it (toggle behavior)"],["li",{},"The reaction summary shows which users reacted with each emoji"],["li",{},"A ",["code",{},"CommentReacted"]," event is dispatched with ",["code",{},"action: 'added'"]," or ",["code",{},"'removed'"]]],["h2",{"id":"customizing-reactions"},"Customizing Reactions"],["p",{},"Override the emoji set in your config:"],["pre",{"className":"language-php shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","code":"// config/comments.php\n'reactions' => [\n    'emoji_set' => [\n        'thumbs_up' => \"\\u{1F44D}\",\n        'thumbs_down' => \"\\u{1F44E}\",\n        'heart' => \"\\u{2764}\\u{FE0F}\",\n        'fire' => \"\\u{1F525}\",\n        'eyes' => \"\\u{1F440}\",\n    ],\n],\n","language":"php","meta":"","style":""},["code",{"__ignoreMap":""},["span",{"class":"line","line":1},["span",{"class":"sHwdD"},"// config/comments.php\n"]],["span",{"class":"line","line":2},["span",{"class":"sMK4o"},"'"],["span",{"class":"sfazB"},"reactions"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," [\n"]],["span",{"class":"line","line":3},["span",{"class":"sMK4o"},"    '"],["span",{"class":"sfazB"},"emoji_set"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," [\n"]],["span",{"class":"line","line":4},["span",{"class":"sMK4o"},"        '"],["span",{"class":"sfazB"},"thumbs_up"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," \""],["span",{"class":"sTEyZ"},"\\u{1F44D}"],["span",{"class":"sMK4o"},"\""],["span",{"class":"sMK4o"},",\n"]],["span",{"class":"line","line":5},["span",{"class":"sMK4o"},"        '"],["span",{"class":"sfazB"},"thumbs_down"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," \""],["span",{"class":"sTEyZ"},"\\u{1F44E}"],["span",{"class":"sMK4o"},"\""],["span",{"class":"sMK4o"},",\n"]],["span",{"class":"line","line":6},["span",{"class":"sMK4o"},"        '"],["span",{"class":"sfazB"},"heart"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," \""],["span",{"class":"sTEyZ"},"\\u{2764}\\u{FE0F}"],["span",{"class":"sMK4o"},"\""],["span",{"class":"sMK4o"},",\n"]],["span",{"class":"line","line":7},["span",{"class":"sMK4o"},"        '"],["span",{"class":"sfazB"},"fire"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," \""],["span",{"class":"sTEyZ"},"\\u{1F525}"],["span",{"class":"sMK4o"},"\""],["span",{"class":"sMK4o"},",\n"]],["span",{"class":"line","line":8},["span",{"class":"sMK4o"},"        '"],["span",{"class":"sfazB"},"eyes"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," \""],["span",{"class":"sTEyZ"},"\\u{1F440}"],["span",{"class":"sMK4o"},"\""],["span",{"class":"sMK4o"},",\n"]],["span",{"class":"line","line":9},["span",{"class":"sMK4o"},"    ],\n"]],["span",{"class":"line","line":10},["span",{"class":"sMK4o"},"],\n"]]]],["p",{},"Keys are stored in the database. If you change a key, existing reactions with the old key will no longer display."],["h2",{"id":"storage"},"Storage"],["p",{},"Reactions are stored in the ",["code",{},"comment_reactions"]," table with a unique constraint on ",["code",{},"(comment_id, user_id, user_type, reaction)"],", ensuring one reaction of each type per user per comment."],["style",{},"html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}"]],"toc":{"title":"","searchDepth":2,"depth":2,"links":[{"id":"default-reactions","depth":2,"text":"Default Reactions"},{"id":"how-reactions-work","depth":2,"text":"How Reactions Work"},{"id":"customizing-reactions","depth":2,"text":"Customizing Reactions"},{"id":"storage","depth":2,"text":"Storage"}]}}


id: docs/2.essentials/5.attachments.md
title: Attachments
description: File uploads for comments.
extension: md
meta: {}
navigation: {"icon":"i-lucide-paperclip"}
path: /essentials/attachments
seo: {"description":"Configure file attachments for comments.","title":"Attachments"}
stem: 2.essentials/5.attachments
__hash__: xrbGvfci8GzWkScxlilgm825K9pTzq8qX89Dvwoimu0
body:
{"type":"minimark","value":[["h2",{"id":"overview"},"Overview"],["p",{},"Comments support file attachments for both images and documents. Images are displayed inline within the comment body, while documents appear as downloadable links."],["h2",{"id":"configuration"},"Configuration"],["pre",{"className":"language-php shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","code":"// config/comments.php\n'attachments' => [\n    'enabled' => true,\n    'disk' => 'public',\n    'max_size' => 10240, // KB (10 MB)\n    'allowed_types' => [\n        'image/jpeg',\n        'image/png',\n        'image/gif',\n        'image/webp',\n        'application/pdf',\n        'text/plain',\n        'application/msword',\n        'application/vnd.openxmlformats-officedocument.wordprocessingml.document',\n    ],\n],\n","language":"php","meta":"","style":""},["code",{"__ignoreMap":""},["span",{"class":"line","line":1},["span",{"class":"sHwdD"},"// config/comments.php\n"]],["span",{"class":"line","line":2},["span",{"class":"sMK4o"},"'"],["span",{"class":"sfazB"},"attachments"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," [\n"]],["span",{"class":"line","line":3},["span",{"class":"sMK4o"},"    '"],["span",{"class":"sfazB"},"enabled"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," true,\n"]],["span",{"class":"line","line":4},["span",{"class":"sMK4o"},"    '"],["span",{"class":"sfazB"},"disk"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," '"],["span",{"class":"sfazB"},"public"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"},",\n"]],["span",{"class":"line","line":5},["span",{"class":"sMK4o"},"    '"],["span",{"class":"sfazB"},"max_size"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sbssI"}," 10240"],["span",{"class":"sMK4o"},","],["span",{"class":"sHwdD"}," // KB (10 MB)\n"]],["span",{"class":"line","line":6},["span",{"class":"sMK4o"},"    '"],["span",{"class":"sfazB"},"allowed_types"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," [\n"]],["span",{"class":"line","line":7},["span",{"class":"sMK4o"},"        '"],["span",{"class":"sfazB"},"image/jpeg"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"},",\n"]],["span",{"class":"line","line":8},["span",{"class":"sMK4o"},"        '"],["span",{"class":"sfazB"},"image/png"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"},",\n"]],["span",{"class":"line","line":9},["span",{"class":"sMK4o"},"        '"],["span",{"class":"sfazB"},"image/gif"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"},",\n"]],["span",{"class":"line","line":10},["span",{"class":"sMK4o"},"        '"],["span",{"class":"sfazB"},"image/webp"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"},",\n"]],["span",{"class":"line","line":11},["span",{"class":"sMK4o"},"        '"],["span",{"class":"sfazB"},"application/pdf"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"},",\n"]],["span",{"class":"line","line":12},["span",{"class":"sMK4o"},"        '"],["span",{"class":"sfazB"},"text/plain"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"},",\n"]],["span",{"class":"line","line":13},["span",{"class":"sMK4o"},"        '"],["span",{"class":"sfazB"},"application/msword"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"},",\n"]],["span",{"class":"line","line":14},["span",{"class":"sMK4o"},"        '"],["span",{"class":"sfazB"},"application/vnd.openxmlformats-officedocument.wordprocessingml.document"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"},",\n"]],["span",{"class":"line","line":15},["span",{"class":"sMK4o"},"    ],\n"]],["span",{"class":"line","line":16},["span",{"class":"sMK4o"},"],\n"]]]],["table",{},["thead",{},["tr",{},["th",{},"Key"],["th",{},"Default"],["th",{},"Description"]]],["tbody",{},["tr",{},["td",{},["code",{},"enabled"]],["td",{},["code",{},"true"]],["td",{},"Show/hide the attachment upload UI"]],["tr",{},["td",{},["code",{},"disk"]],["td",{},["code",{},"'public'"]],["td",{},"Laravel filesystem disk for storage"]],["tr",{},["td",{},["code",{},"max_size"]],["td",{},["code",{},"10240"]],["td",{},"Maximum file size in kilobytes"]],["tr",{},["td",{},["code",{},"allowed_types"]],["td",{},"images, pdf, text, word"],["td",{},"Array of allowed MIME types"]]]],["h2",{"id":"disabling-attachments"},"Disabling Attachments"],["pre",{"className":"language-php shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","code":"'attachments' => [\n    'enabled' => false,\n],\n","language":"php","meta":"","style":""},["code",{"__ignoreMap":""},["span",{"class":"line","line":1},["span",{"class":"sMK4o"},"'"],["span",{"class":"sfazB"},"attachments"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," [\n"]],["span",{"class":"line","line":2},["span",{"class":"sMK4o"},"    '"],["span",{"class":"sfazB"},"enabled"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," false,\n"]],["span",{"class":"line","line":3},["span",{"class":"sMK4o"},"],\n"]]]],["p",{},"This removes the file upload UI from the comment form entirely."],["h2",{"id":"storage"},"Storage"],["p",{},"Attachments are stored via Livewire's file upload mechanism. Each attachment record tracks:"],["ul",{},["li",{},["code",{},"file_path"]," -- Path on the configured disk"],["li",{},["code",{},"original_name"]," -- Original filename for display"],["li",{},["code",{},"mime_type"]," -- MIME type for rendering decisions"],["li",{},["code",{},"size"]," -- File size in bytes"],["li",{},["code",{},"disk"]," -- Storage disk name"]],["p",{},"When a comment is deleted, its attachments are cascade deleted from the database. The physical files are removed from the disk."],["h2",{"id":"helper-methods"},"Helper Methods"],["p",{},"The ",["code",{},"CommentAttachment"]," model provides:"],["pre",{"className":"language-php shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","code":"$attachment->isImage();       // Check if attachment is an image\n$attachment->url();           // Get the storage URL\n$attachment->formattedSize(); // Human-readable size (e.g., \"2.5 MB\")\n","language":"php","meta":"","style":""},["code",{"__ignoreMap":""},["span",{"class":"line","line":1},["span",{"class":"sMK4o"},"$"],["span",{"class":"sTEyZ"},"attachment"],["span",{"class":"sMK4o"},"->"],["span",{"class":"s2Zo4"},"isImage"],["span",{"class":"sMK4o"},"();"],["span",{"class":"sHwdD"},"       // Check if attachment is an image\n"]],["span",{"class":"line","line":2},["span",{"class":"sMK4o"},"$"],["span",{"class":"sTEyZ"},"attachment"],["span",{"class":"sMK4o"},"->"],["span",{"class":"s2Zo4"},"url"],["span",{"class":"sMK4o"},"();"],["span",{"class":"sHwdD"},"           // Get the storage URL\n"]],["span",{"class":"line","line":3},["span",{"class":"sMK4o"},"$"],["span",{"class":"sTEyZ"},"attachment"],["span",{"class":"sMK4o"},"->"],["span",{"class":"s2Zo4"},"formattedSize"],["span",{"class":"sMK4o"},"();"],["span",{"class":"sHwdD"}," // Human-readable size (e.g., \"2.5 MB\")\n"]]]],["style",{},"html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}"]],"toc":{"title":"","searchDepth":2,"depth":2,"links":[{"id":"overview","depth":2,"text":"Overview"},{"id":"configuration","depth":2,"text":"Configuration"},{"id":"disabling-attachments","depth":2,"text":"Disabling Attachments"},{"id":"storage","depth":2,"text":"Storage"},{"id":"helper-methods","depth":2,"text":"Helper Methods"}]}}


id: docs/2.essentials/6.notifications.md
title: Notifications
description: Comment notifications, subscriptions, and real-time updates.
extension: md
meta: {}
navigation: {"icon":"i-lucide-bell"}
path: /essentials/notifications
stem: 2.essentials/6.notifications
__hash__: IShzf0gxRwqSzEvhZKCCHfv_bSAPbP2T6TYVaQvFsEo
body:
{"type":"minimark","value":[["h2",{"id":"notification-types"},"Notification Types"],["p",{},"Two notification classes are included:"],["h3",{"id":"commentrepliednotification"},"CommentRepliedNotification"],["p",{},"Sent to all thread subscribers when a new comment or reply is posted. The comment author is excluded from receiving their own notification."],["h3",{"id":"usermentionednotification"},"UserMentionedNotification"],["p",{},"Sent to a user when they are @mentioned in a comment. Self-mentions are ignored."],["h2",{"id":"channels"},"Channels"],["pre",{"className":"language-php shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","code":"// config/comments.php\n'notifications' => [\n    'channels' => ['database'],\n    'enabled' => true,\n],\n","language":"php","meta":"","style":""},["code",{"__ignoreMap":""},["span",{"class":"line","line":1},["span",{"class":"sHwdD"},"// config/comments.php\n"]],["span",{"class":"line","line":2},["span",{"class":"sMK4o"},"'"],["span",{"class":"sfazB"},"notifications"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," [\n"]],["span",{"class":"line","line":3},["span",{"class":"sMK4o"},"    '"],["span",{"class":"sfazB"},"channels"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," ["],["span",{"class":"sMK4o"},"'"],["span",{"class":"sfazB"},"database"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"},"],\n"]],["span",{"class":"line","line":4},["span",{"class":"sMK4o"},"    '"],["span",{"class":"sfazB"},"enabled"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," true,\n"]],["span",{"class":"line","line":5},["span",{"class":"sMK4o"},"],\n"]]]],["p",{},"Available channels: ",["code",{},"'database'"]," and ",["code",{},"'mail'"],". Add both to send email notifications alongside database notifications:"],["pre",{"className":"language-php shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","code":"'notifications' => [\n    'channels' => ['database', 'mail'],\n    'enabled' => true,\n],\n","language":"php","meta":"","style":""},["code",{"__ignoreMap":""},["span",{"class":"line","line":1},["span",{"class":"sMK4o"},"'"],["span",{"class":"sfazB"},"notifications"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," [\n"]],["span",{"class":"line","line":2},["span",{"class":"sMK4o"},"    '"],["span",{"class":"sfazB"},"channels"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," ["],["span",{"class":"sMK4o"},"'"],["span",{"class":"sfazB"},"database"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"},","],["span",{"class":"sMK4o"}," '"],["span",{"class":"sfazB"},"mail"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"},"],\n"]],["span",{"class":"line","line":3},["span",{"class":"sMK4o"},"    '"],["span",{"class":"sfazB"},"enabled"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," true,\n"]],["span",{"class":"line","line":4},["span",{"class":"sMK4o"},"],\n"]]]],["h2",{"id":"subscriptions"},"Subscriptions"],["p",{},"Users can subscribe to comment threads on any commentable model. Subscribers receive notifications when new comments are posted."],["h3",{"id":"auto-subscribe"},"Auto-Subscribe"],["pre",{"className":"language-php shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","code":"'subscriptions' => [\n    'auto_subscribe' => true,\n],\n","language":"php","meta":"","style":""},["code",{"__ignoreMap":""},["span",{"class":"line","line":1},["span",{"class":"sMK4o"},"'"],["span",{"class":"sfazB"},"subscriptions"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," [\n"]],["span",{"class":"line","line":2},["span",{"class":"sMK4o"},"    '"],["span",{"class":"sfazB"},"auto_subscribe"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," true,\n"]],["span",{"class":"line","line":3},["span",{"class":"sMK4o"},"],\n"]]]],["p",{},"When enabled:"],["ul",{},["li",{},"Users are auto-subscribed when they post a comment"],["li",{},"Users are auto-subscribed when they are @mentioned"]],["h3",{"id":"manual-subscription"},"Manual Subscription"],["p",{},"Users can toggle their subscription using the subscribe/unsubscribe button in the comments UI."],["h3",{"id":"programmatic-access"},"Programmatic Access"],["pre",{"className":"language-php shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","code":"use Relaticle\\Comments\\CommentSubscription;\n\n// Check subscription status\nCommentSubscription::isSubscribed($commentable, $user);\n\n// Subscribe/unsubscribe\nCommentSubscription::subscribe($commentable, $user);\nCommentSubscription::unsubscribe($commentable, $user);\n\n// Get all subscribers for a commentable\n$subscribers = CommentSubscription::subscribersFor($commentable);\n","language":"php","meta":"","style":""},["code",{"__ignoreMap":""},["span",{"class":"line","line":1},["span",{"class":"sbssI"},"use"],["span",{"class":"sTEyZ"}," Relaticle"],["span",{"class":"sMK4o"},"\\"],["span",{"class":"sTEyZ"},"Comments"],["span",{"class":"sMK4o"},"\\"],["span",{"class":"sTEyZ"},"CommentSubscription"],["span",{"class":"sMK4o"},";\n"]],["span",{"class":"line","line":2},["span",{"emptyLinePlaceholder":true},"\n"]],["span",{"class":"line","line":3},["span",{"class":"sHwdD"},"// Check subscription status\n"]],["span",{"class":"line","line":4},["span",{"class":"sBMFI"},"CommentSubscription"],["span",{"class":"sMK4o"},"::"],["span",{"class":"s2Zo4"},"isSubscribed"],["span",{"class":"sMK4o"},"($"],["span",{"class":"sTEyZ"},"commentable"],["span",{"class":"sMK4o"},","],["span",{"class":"sMK4o"}," $"],["span",{"class":"sTEyZ"},"user"],["span",{"class":"sMK4o"},");\n"]],["span",{"class":"line","line":5},["span",{"emptyLinePlaceholder":true},"\n"]],["span",{"class":"line","line":6},["span",{"class":"sHwdD"},"// Subscribe/unsubscribe\n"]],["span",{"class":"line","line":7},["span",{"class":"sBMFI"},"CommentSubscription"],["span",{"class":"sMK4o"},"::"],["span",{"class":"s2Zo4"},"subscribe"],["span",{"class":"sMK4o"},"($"],["span",{"class":"sTEyZ"},"commentable"],["span",{"class":"sMK4o"},","],["span",{"class":"sMK4o"}," $"],["span",{"class":"sTEyZ"},"user"],["span",{"class":"sMK4o"},");\n"]],["span",{"class":"line","line":8},["span",{"class":"sBMFI"},"CommentSubscription"],["span",{"class":"sMK4o"},"::"],["span",{"class":"s2Zo4"},"unsubscribe"],["span",{"class":"sMK4o"},"($"],["span",{"class":"sTEyZ"},"commentable"],["span",{"class":"sMK4o"},","],["span",{"class":"sMK4o"}," $"],["span",{"class":"sTEyZ"},"user"],["span",{"class":"sMK4o"},");\n"]],["span",{"class":"line","line":9},["span",{"emptyLinePlaceholder":true},"\n"]],["span",{"class":"line","line":10},["span",{"class":"sHwdD"},"// Get all subscribers for a commentable\n"]],["span",{"class":"line","line":11},["span",{"class":"sMK4o"},"$"],["span",{"class":"sTEyZ"},"subscribers "],["span",{"class":"sMK4o"},"="],["span",{"class":"sBMFI"}," CommentSubscription"],["span",{"class":"sMK4o"},"::"],["span",{"class":"s2Zo4"},"subscribersFor"],["span",{"class":"sMK4o"},"($"],["span",{"class":"sTEyZ"},"commentable"],["span",{"class":"sMK4o"},");\n"]]]],["h2",{"id":"events"},"Events"],["table",{},["thead",{},["tr",{},["th",{},"Event"],["th",{},"Trigger"],["th",{},"Broadcasts"]]],["tbody",{},["tr",{},["td",{},["code",{},"CommentCreated"]],["td",{},"New comment or reply"],["td",{},"Yes"]],["tr",{},["td",{},["code",{},"CommentUpdated"]],["td",{},"Comment edited"],["td",{},"Yes"]],["tr",{},["td",{},["code",{},"CommentDeleted"]],["td",{},"Comment soft-deleted"],["td",{},"Yes"]],["tr",{},["td",{},["code",{},"CommentReacted"]],["td",{},"Reaction added/removed"],["td",{},"Yes"]],["tr",{},["td",{},["code",{},"UserMentioned"]],["td",{},"User @mentioned"],["td",{},"No"]]]],["h2",{"id":"real-time-updates"},"Real-time Updates"],["h3",{"id":"broadcasting"},"Broadcasting"],["p",{},"Enable broadcasting for instant updates across browser sessions:"],["pre",{"className":"language-php shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","code":"// config/comments.php\n'broadcasting' => [\n    'enabled' => true,\n    'channel_prefix' => 'comments',\n],\n","language":"php","meta":"","style":""},["code",{"__ignoreMap":""},["span",{"class":"line","line":1},["span",{"class":"sHwdD"},"// config/comments.php\n"]],["span",{"class":"line","line":2},["span",{"class":"sMK4o"},"'"],["span",{"class":"sfazB"},"broadcasting"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," [\n"]],["span",{"class":"line","line":3},["span",{"class":"sMK4o"},"    '"],["span",{"class":"sfazB"},"enabled"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," true,\n"]],["span",{"class":"line","line":4},["span",{"class":"sMK4o"},"    '"],["span",{"class":"sfazB"},"channel_prefix"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," '"],["span",{"class":"sfazB"},"comments"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"},",\n"]],["span",{"class":"line","line":5},["span",{"class":"sMK4o"},"],\n"]]]],["p",{},"Events are broadcast on private channels: ",["code",{},"{prefix}.{commentable_type}.{commentable_id}"]],["p",{},"This requires Laravel Echo and a broadcasting driver (Pusher, Ably, etc.) configured in your application."],["h3",{"id":"polling-fallback"},"Polling Fallback"],["p",{},"When broadcasting is disabled, the Livewire component polls for updates:"],["pre",{"className":"language-php shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","code":"'polling' => [\n    'interval' => '10s',\n],\n","language":"php","meta":"","style":""},["code",{"__ignoreMap":""},["span",{"class":"line","line":1},["span",{"class":"sMK4o"},"'"],["span",{"class":"sfazB"},"polling"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," [\n"]],["span",{"class":"line","line":2},["span",{"class":"sMK4o"},"    '"],["span",{"class":"sfazB"},"interval"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," '"],["span",{"class":"sfazB"},"10s"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"},",\n"]],["span",{"class":"line","line":3},["span",{"class":"sMK4o"},"],\n"]]]],["p",{},"Set to ",["code",{},"null"]," to disable polling entirely."],["h2",{"id":"disabling-notifications"},"Disabling Notifications"],["pre",{"className":"language-php shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","code":"'notifications' => [\n    'enabled' => false,\n],\n","language":"php","meta":"","style":""},["code",{"__ignoreMap":""},["span",{"class":"line","line":1},["span",{"class":"sMK4o"},"'"],["span",{"class":"sfazB"},"notifications"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," [\n"]],["span",{"class":"line","line":2},["span",{"class":"sMK4o"},"    '"],["span",{"class":"sfazB"},"enabled"],["span",{"class":"sMK4o"},"'"],["span",{"class":"sMK4o"}," =>"],["span",{"class":"sMK4o"}," false,\n"]],["span",{"class":"line","line":3},["span",{"class":"sMK4o"},"],\n"]]]],["p",{},"This disables all notification dispatching. Subscriptions and events still work, but no notifications are sent."],["style",{},"html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}"]],"toc":{"title":"","searchDepth":2,"depth":2,"links":[{"id":"notification-types","depth":2,"text":"Notification Types","children":[{"id":"commentrepliednotification","depth":3,"text":"CommentRepliedNotification"},{"id":"usermentionednotification","depth":3,"text":"UserMentionedNotification"}]},{"id":"channels","depth":2,"text":"Channels"},{"id":"subscriptions","depth":2,"text":"Subscriptions","children":[{"id":"auto-subscribe","depth":3,"text":"Auto-Subscribe"},{"id":"manual-subscription","depth":3,"text":"Manual Subscription"},{"id":"programmatic-access","depth":3,"text":"Programmatic Access"}]},{"id":"events","depth":2,"text":"Events"},{"id":"real-time-updates","depth":2,"text":"Real-time Updates","children":[{"id":"broadcasting","depth":3,"text":"Broadcasting"},{"id":"polling-fallback","depth":3,"text":"Polling Fallback"}]},{"id":"disabling-notifications","depth":2,"text":"Disabling Notifications"}]}}

seo:
{"description":"Configure comment notifications, subscriptions, broadcasting, and polling.","title":"Notifications"}


id: docs/2.essentials/7.database-schema.md
title: Database Schema
description: Tables, relationships, and indexes used by the Comments package.
extension: md
meta: {}
navigation: {"icon":"i-lucide-database"}
path: /essentials/database-schema
seo: {"description":"Database schema reference for the Comments package.","title":"Database Schema"}
stem: 2.essentials/7.database-schema
__hash__: Yte6rX8x8upsowLURd9q9HFQY5Q9t4nTMbfY0ErhnKY
body:
{"type":"minimark","value":[["h2",{"id":"tables"},"Tables"],["p",{},"Five tables are created by the package migrations."],["h3",{"id":"comments"},"comments"],["p",{},"The main comments table with polymorphic relationships and threading support."],["table",{},["thead",{},["tr",{},["th",{},"Column"],["th",{},"Type"],["th",{},"Description"]]],["tbody",{},["tr",{},["td",{},["code",{},"id"]],["td",{},"bigint"],["td",{},"Primary key"]],["tr",{},["td",{},["code",{},"commentable_type"]],["td",{},"string"],["td",{},"Polymorphic model type"]],["tr",{},["td",{},["code",{},"commentable_id"]],["td",{},"bigint"],["td",{},"Polymorphic model ID"]],["tr",{},["td",{},["code",{},"user_type"]],["td",{},"string"],["td",{},"Commenter model type"]],["tr",{},["td",{},["code",{},"user_id"]],["td",{},"bigint"],["td",{},"Commenter model ID"]],["tr",{},["td",{},["code",{},"parent_id"]],["td",{},"bigint (nullable)"],["td",{},"Parent comment for replies"]],["tr",{},["td",{},["code",{},"body"]],["td",{},"text"],["td",{},"HTML comment content"]],["tr",{},["td",{},["code",{},"edited_at"]],["td",{},"timestamp (nullable)"],["td",{},"When the comment was last edited"]],["tr",{},["td",{},["code",{},"deleted_at"]],["td",{},"timestamp (nullable)"],["td",{},"Soft delete timestamp"]],["tr",{},["td",{},["code",{},"created_at"]],["td",{},"timestamp"],["td",{}]],["tr",{},["td",{},["code",{},"updated_at"]],["td",{},"timestamp"],["td",{}]]]],["p",{},["strong",{},"Indexes:"]," ",["code",{},"(commentable_type, commentable_id, parent_id)"]],["h3",{"id":"comment_reactions"},"comment_reactions"],["p",{},"Tracks emoji reactions per user per comment."],["table",{},["thead",{},["tr",{},["th",{},"Column"],["th",{},"Type"],["th",{},"Description"]]],["tbody",{},["tr",{},["td",{},["code",{},"id"]],["td",{},"bigint"],["td",{},"Primary key"]],["tr",{},["td",{},["code",{},"comment_id"]],["td",{},"bigint"],["td",{},"Foreign key to comments"]],["tr",{},["td",{},["code",{},"user_type"]],["td",{},"string"],["td",{},"Reactor model type"]],["tr",{},["td",{},["code",{},"user_id"]],["td",{},"bigint"],["td",{},"Reactor model ID"]],["tr",{},["td",{},["code",{},"reaction"]],["td",{},"string"],["td",{},"Reaction key (e.g., ",["code",{},"thumbs_up"],")"]],["tr",{},["td",{},["code",{},"created_at"]],["td",{},"timestamp"],["td",{}]]]],["p",{},["strong",{},"Unique constraint:"]," ",["code",{},"(comment_id, user_id, user_type, reaction)"]],["h3",{"id":"comment_mentions"},"comment_mentions"],["p",{},"Tracks @mentioned users per comment."],["table",{},["thead",{},["tr",{},["th",{},"Column"],["th",{},"Type"],["th",{},"Description"]]],["tbody",{},["tr",{},["td",{},["code",{},"id"]],["td",{},"bigint"],["td",{},"Primary key"]],["tr",{},["td",{},["code",{},"comment_id"]],["td",{},"bigint"],["td",{},"Foreign key to comments"]],["tr",{},["td",{},["code",{},"user_type"]],["td",{},"string"],["td",{},"Mentioned user model type"]],["tr",{},["td",{},["code",{},"user_id"]],["td",{},"bigint"],["td",{},"Mentioned user model ID"]],["tr",{},["td",{},["code",{},"created_at"]],["td",{},"timestamp"],["td",{}]]]],["p",{},["strong",{},"Unique constraint:"]," ",["code",{},"(comment_id, user_id, user_type)"]],["h3",{"id":"comment_subscriptions"},"comment_subscriptions"],["p",{},"Tracks which users are subscribed to comment threads on specific models."],["table",{},["thead",{},["tr",{},["th",{},"Column"],["th",{},"Type"],["th",{},"Description"]]],["tbody",{},["tr",{},["td",{},["code",{},"id"]],["td",{},"bigint"],["td",{},"Primary key"]],["tr",{},["td",{},["code",{},"commentable_type"]],["td",{},"string"],["td",{},"Subscribed model type"]],["tr",{},["td",{},["code",{},"commentable_id"]],["td",{},"bigint"],["td",{},"Subscribed model ID"]],["tr",{},["td",{},["code",{},"user_type"]],["td",{},"string"],["td",{},"Subscriber model type"]],["tr",{},["td",{},["code",{},"user_id"]],["td",{},"bigint"],["td",{},"Subscriber model ID"]],["tr",{},["td",{},["code",{},"created_at"]],["td",{},"timestamp"],["td",{}]]]],["p",{},["strong",{},"Unique constraint:"]," ",["code",{},"(commentable_type, commentable_id, user_type, user_id)"]],["h3",{"id":"comment_attachments"},"comment_attachments"],["p",{},"Stores file attachment metadata for comments."],["table",{},["thead",{},["tr",{},["th",{},"Column"],["th",{},"Type"],["th",{},"Description"]]],["tbody",{},["tr",{},["td",{},["code",{},"id"]],["td",{},"bigint"],["td",{},"Primary key"]],["tr",{},["td",{},["code",{},"comment_id"]],["td",{},"bigint"],["td",{},"Foreign key to comments"]],["tr",{},["td",{},["code",{},"file_path"]],["td",{},"string"],["td",{},"Path on the storage disk"]],["tr",{},["td",{},["code",{},"original_name"]],["td",{},"string"],["td",{},"Original uploaded filename"]],["tr",{},["td",{},["code",{},"mime_type"]],["td",{},"string"],["td",{},"File MIME type"]],["tr",{},["td",{},["code",{},"size"]],["td",{},"bigint"],["td",{},"File size in bytes"]],["tr",{},["td",{},["code",{},"disk"]],["td",{},"string"],["td",{},"Laravel filesystem disk"]],["tr",{},["td",{},["code",{},"created_at"]],["td",{},"timestamp"],["td",{}]],["tr",{},["td",{},["code",{},"updated_at"]],["td",{},"timestamp"],["td",{}]]]],["h2",{"id":"relationships"},"Relationships"],["pre",{"className":["language-text"],"code":"Commentable Model (e.g., Project)\n  └── comments (morphMany)\n        ├── user (morphTo → User)\n        ├── parent (belongsTo → Comment)\n        ├── replies (hasMany → Comment)\n        ├── reactions (hasMany → CommentReaction)\n        ├── attachments (hasMany → CommentAttachment)\n        └── mentions (morphToMany → User)\n","language":"text"},["code",{"__ignoreMap":""},"Commentable Model (e.g., Project)\n  └── comments (morphMany)\n        ├── user (morphTo → User)\n        ├── parent (belongsTo → Comment)\n        ├── replies (hasMany → Comment)\n        ├── reactions (hasMany → CommentReaction)\n        ├── attachments (hasMany → CommentAttachment)\n        └── mentions (morphToMany → User)\n"]],["p",{},"All relationships are polymorphic, allowing the same comment system to work across any number of models in your application."]],"toc":{"title":"","searchDepth":2,"depth":2,"links":[{"id":"tables","depth":2,"text":"Tables","children":[{"id":"comments","depth":3,"text":"comments"},{"id":"comment_reactions","depth":3,"text":"comment_reactions"},{"id":"comment_mentions","depth":3,"text":"comment_mentions"},{"id":"comment_subscriptions","depth":3,"text":"comment_subscriptions"},{"id":"comment_attachments","depth":3,"text":"comment_attachments"}]},{"id":"relationships","depth":2,"text":"Relationships"}]}}


id: docs/4.community/1.contributing.md
title: Contributing
description: How to contribute to Comments
extension: md
meta: {}
navigation: {"icon":"i-lucide-heart-handshake"}
path: /community/contributing
seo: {"title":"Contributing","description":"How to contribute to Comments"}
stem: 4.community/1.contributing
__hash__: WizyvP9psZ6kzi7GfqkI0Riqpld0llpTEbjKit0RwM0
body:
{"type":"minimark","value":[["h2",{"id":"quick-start"},"Quick Start"],["ol",{},["li",{},["strong",{},"Fork"]," the repository"],["li",{},["strong",{},"Create"]," a feature branch"],["li",{},["strong",{},"Make"]," your changes"],["li",{},["strong",{},"Run"]," tests: ",["code",{},"composer test"]],["li",{},["strong",{},"Submit"]," a pull request"]],["h2",{"id":"guidelines"},"Guidelines"],["ul",{},["li",{},"Follow the existing code style"],["li",{},"Add tests for new features"],["li",{},"Update documentation as needed"],["li",{},"One feature per pull request"]],["h2",{"id":"development-commands"},"Development Commands"],["pre",{"className":"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","code":"# Run tests\ncomposer test\n\n# Format code\ncomposer pint\n\n# Static analysis\ncomposer analyse\n","language":"bash","meta":"","style":""},["code",{"__ignoreMap":""},["span",{"class":"line","line":1},["span",{"class":"sHwdD"},"# Run tests\n"]],["span",{"class":"line","line":2},["span",{"class":"sBMFI"},"composer"],["span",{"class":"sfazB"}," test\n"]],["span",{"class":"line","line":3},["span",{"emptyLinePlaceholder":true},"\n"]],["span",{"class":"line","line":4},["span",{"class":"sHwdD"},"# Format code\n"]],["span",{"class":"line","line":5},["span",{"class":"sBMFI"},"composer"],["span",{"class":"sfazB"}," pint\n"]],["span",{"class":"line","line":6},["span",{"emptyLinePlaceholder":true},"\n"]],["span",{"class":"line","line":7},["span",{"class":"sHwdD"},"# Static analysis\n"]],["span",{"class":"line","line":8},["span",{"class":"sBMFI"},"composer"],["span",{"class":"sfazB"}," analyse\n"]]]],["h2",{"id":"need-help"},"Need Help?"],["ul",{},["li",{},["a",{"href":"https://github.com/relaticle/comments/issues","rel":["nofollow"]},"Open an issue"]," for bugs or questions"],["li",{},"Check ",["a",{"href":"https://github.com/relaticle/comments/issues","rel":["nofollow"]},"existing issues"]," first"]],["style",{},"html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}"]],"toc":{"title":"","searchDepth":2,"depth":2,"links":[{"id":"quick-start","depth":2,"text":"Quick Start"},{"id":"guidelines","depth":2,"text":"Guidelines"},{"id":"development-commands","depth":2,"text":"Development Commands"},{"id":"need-help","depth":2,"text":"Need Help?"}]}}


id: docs/4.community/2.license.md
title: License
description: MIT License terms and what it means for you
extension: md
meta: {}
navigation: {"icon":"i-lucide-scale"}
path: /community/license
seo: {"title":"License","description":"MIT License terms and what it means for you"}
stem: 4.community/2.license
__hash__: 0vOJT-zB-Vz0zBt_oMaewM8TIacFMi_ctus0AaWjZAI
body:
{"type":"minimark","value":[["h2",{"id":"mit-license"},"MIT License"],["pre",{"className":["language-text"],"code":"Copyright (c) Relaticle\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n","language":"text"},["code",{"__ignoreMap":""},"Copyright (c) Relaticle\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n"]],["h2",{"id":"what-this-means"},"What This Means"],["p",{},"You ",["strong",{},"can"]," use Comments in commercial projects.\nYou ",["strong",{},"can"]," modify and distribute it.\nYou ",["strong",{},"can"]," use it in closed source projects.\nYou ",["strong",{},"can"]," sell applications that include it."],["p",{},"Just include the license notice in your copy."]],"toc":{"title":"","searchDepth":2,"depth":2,"links":[{"id":"mit-license","depth":2,"text":"MIT License"},{"id":"what-this-means","depth":2,"text":"What This Means"}]}}


