eloquent-works / persona
Laravel Persona gives your users elegant public profiles with slugs, bios, avatars, links, visibility, and profile pages.
Requires
- php: ^8.2
- illuminate/contracts: ^11.15|^12.0|^13.0
- illuminate/database: ^11.15|^12.0|^13.0
- illuminate/routing: ^11.15|^12.0|^13.0
- illuminate/support: ^11.15|^12.0|^13.0
Requires (Dev)
- larastan/larastan: ^3.10
- laravel/pint: ^1.18
- orchestra/testbench: ^9.0|^10.0|^11.0
- phpunit/phpunit: ^11.0
This package is not auto-updated.
Last update: 2026-07-25 20:21:48 UTC
README
Elegant public profile tools for Laravel applications.
Laravel Persona gives your Eloquent user model a clean way to manage public profiles, unique usernames, username change tokens, display names, mottos, bios, avatars, banners, social links, custom links, visibility, publishing, comments, and profile view tracking.
$profile = $user->persona()->create([ 'slug' => 'signal-nick', 'display_name' => 'Nick', 'headline' => 'Laravel Developer', 'bio' => 'I build Laravel applications and packages.', 'is_public' => true, 'published_at' => now(), ]); $profile->recordView(); $profile->avatarUrl(); $profile->bannerUrl(); $profile->url();
✨ Highlights
- Public user profiles for Eloquent models
- Slug-based profile URLs
- Unique usernames backed by profile slugs
- Configurable username change tokens
- Username token earning intervals
- Maximum username token balances
- Display names, headlines, mottos, bios, and locations
- Avatar and banner media support
- Website, social links, and custom links
- Public and private profile visibility
- Optional profile publishing controls
- Profile view tracking
- Optional guest comments
- Nested comments with configurable depth
- Query scopes for public, published, and visible profiles
- Publishable views
- Optional built-in profile routes
- Configurable models, table names, route names, storage disk, and validation limits
📋 Requirements
| Laravel | PHP | Orchestra Testbench |
|---|---|---|
| 12.x | 8.2+ | 10.x |
| 13.x | 8.3+ | 11.x |
📦 Installation
Install the package through Composer:
composer require eloquent-works/persona
Install Persona:
php artisan persona:install php artisan migrate
Add HasPersona to your account model:
<?php namespace App\Models; use EloquentWorks\Persona\Traits\HasPersona; use Illuminate\Foundation\Auth\User as Authenticatable; class User extends Authenticatable { use HasPersona; }
🙋 Profiles
Create a profile:
$profile = $user->persona()->create([ 'slug' => 'john-doe', 'display_name' => 'John Doe', 'headline' => 'Laravel Developer', 'motto' => 'Ship clean code.', 'bio' => 'I build Laravel applications and packages.', 'location' => 'Kansas', 'is_public' => true, 'published_at' => now(), ]);
Read profile URLs and media URLs:
$profile->url(); $profile->avatarUrl(); $profile->bannerUrl();
Track profile views:
$profile->recordView();
🪪 Username Tokens
Persona can limit username changes with tokens. By default, a profile can earn tokens over time and spend them when changing usernames.
$profile->usernameTokens(); $profile->canChangeUsername(); $profile->changeUsername('signal-nick');
You can also use helpers on the user model:
$user->personaUsernameTokens(); $user->canChangePersonaUsername(); $user->changePersonaUsername('signal-nick');
🔎 Query Helpers
use EloquentWorks\Persona\Models\Persona; Persona::query()->public()->get(); Persona::query()->published()->get(); Persona::query()->visible()->get();
🔗 Links and Social Profiles
Persona supports profile links and social links.
$profile->update([ 'website_url' => 'https://example.com', 'links' => [ [ 'label' => 'GitHub', 'url' => 'https://github.com/EloquentWorks', ], ], 'social_links' => [ 'github' => 'EloquentWorks', ], ]);
💬 Comments
When comments are enabled, profiles can accept comments with configurable depth and guest behavior.
$comment = $profile->comments()->create([ 'body' => 'Great profile!', 'user_id' => auth()->id(), ]); $comment->replies()->create([ 'body' => 'Thank you!', 'user_id' => $profile->user_id, ]);
🛣️ Routes
Persona can register optional profile routes.
Route::get('/@{persona:slug}', ShowPersonaController::class) ->name('persona.show');
View a profile:
route('persona.show', $profile);
⚙️ Configuration
Publish the configuration file:
php artisan vendor:publish --tag=persona-config
🧰 Commands
php artisan persona:install
Publish assets manually:
php artisan vendor:publish --tag=persona-config php artisan vendor:publish --tag=persona-migrations php artisan vendor:publish --tag=persona-views
📚 Documentation
Full documentation is available in the docs directory:
- Installation
- Configuration
- Architecture
- Profiles
- Usernames and Tokens
- Links and Media
- Visibility and Publishing
- Comments
- Routes
- Views and Blade
- Commands
- Customization
- Security
- Testing
✅ Quality Checks
composer validate --strict composer quality
Or run the tools separately:
composer format
composer analyse
composer test
🔐 Security
Treat public profile input as user-generated content. Validate URLs, escape rendered content, authorize profile edits, and avoid exposing private profile data through search, sitemaps, or public routes.
Security vulnerabilities should be reported privately according to SECURITY.md.
🤝 Contributing
See CONTRIBUTING.md and CODE_OF_CONDUCT.md.
📄 License
Laravel Persona is open-source software licensed under the MIT License.