flarum/nicknames
Flarum extension that lets members set an optional nickname and show it across the forum. Users manage their nickname from profile settings, while usernames remain available for login and identification. A simple way to add friendlier display names to your community.
flarum/nicknames is a bundled Flarum extension that adds an optional nickname to users and a display_name fallback that returns the nickname when set, otherwise the username. Most installs already have it; verify with composer show flarum/nicknames before requiring it explicitly.
Minimal steps:
composer require flarum/nicknames
php flarum migrate # adds the nickname column if not present
php flarum cache:clear
Enable it in the admin panel if it is disabled, then look at these files first:
extend.php — serializer attributes, settings (min, max, unique, regex, set_on_registration), frontend registration.migrations/*_add_nickname_to_users.php — the only schema change.src/Listeners/SaveNicknameToDatabase.php and src/Validators/NicknameValidator.php — validation on every user save.js/src/forum/ — settings page field, registration field, user card, and the User model extension.First use case — set a nickname as an admin and confirm the fallback:
PATCH /api/users/5
Authorization: Token <admin-token>
Content-Type: application/json
{"data":{"attributes":{"nickname":"Ada"}}}
Then GET /api/users/5 and check data.attributes.nickname. Posts and user cards should render "Ada" instead of the username. In PHP, $user->display_name is the value you want; in JS, user.displayName().
Always read display_name, not nickname, when rendering. The whole point of the extension is the fallback. $user->nickname is nullable; $user->display_name (or $user->getDisplayNameAttribute() on older cores) is the safe value.
// Bad: breaks for users without a nickname
$name = $user->nickname;
// Good
$name = $user->display_name;
Frontend components. Use the model method so you inherit the fallback and stay compatible with core changes:
import User from 'flarum/common/models/User';
// In a component
const name = user.displayName(); // nickname or username
const raw = user.nickname(); // may be null/undefined
For mention pills, user cards, and post headers, prefer overriding the existing component via the extension's own component names rather than reimplementing the logic.
Adding your own serializer attribute that depends on the display name:
use Flarum\Api\Serializer\UserSerializer;
use Flarum\Extend;
return [
(new Extend\ApiSerializer(UserSerializer::class))
->attributes(function (UserSerializer $serializer, $user) {
return ['initials' => mb_substr($user->display_name, 0, 1)];
}),
];
Normalizing nicknames on save. The extension validates on Flarum\User\Event\Saving. If you also listen to that event, order matters — Laravel runs higher priority first, so use a negative priority to normalize before the extension's validator runs, or a positive one to post-process.
(new Extend\Event())->listen(Saving::class, function (Saving $event) {
if (isset($event->data['attributes']['nickname'])) {
$event->data['attributes']['nickname'] =
trim($event->data['attributes']['nickname']);
}
});
Registration and SSO. Turn on "set nickname on registration" in admin, and the registration modal ships a nickname attribute in its POST /api/users payload. If you use OAuth/SSO, make sure your provider populates nickname during user creation; otherwise users land with an empty nickname and fall back to username forever unless they visit settings.
Tests and seeders. Factories can set the column directly, and assertions should target the fallback:
$user = User::factory()->create(['nickname' => 'ada']);
$this->assertSame('ada', $user->display_name);
$plain = User::factory()->create(['nickname' => null]);
$this->assertSame($plain->username, $plain->display_name);
When testing validation, set the extension settings explicitly (min/max/unique/regex) so your tests don't depend on the admin panel state.
API clients. Treat nickname as a writable attribute on the user resource and displayName (when serialized) as read-only. Don't write username to change the display name — that will break login and mention resolution.
"" to clear a nickname, while min > 0 validation can reject it. Decide whether clearing is allowed and make the frontend consistent with the validator.unique setting is application-level only. Concurrent saves can race. If uniqueness is a hard requirement, add a unique index on users.nickname and handle QueryException, and be aware that case sensitivity depends on the DB collation.preg_match. Bad delimiters or unbalanced groups can break every user save. Test the exact string with your PHP build, and always store a valid pattern or an empty value.save().@nickname may not link. Set expectations in your community docs.nickname unless you add your own index and resolver.displayName/display_name was not uniformly available in early 1.x. If you support multiple minors, feature-detect: method_exists($user, 'getDisplayNameAttribute') on the backend, and guard user.displayName ? user.displayName() : user.username() in JS.nickname column, the migration may collide. Check Schema::hasColumn('users', 'nickname') before rolling out to existing databases.php flarum cache:clear after changing min/max/regex programmatically. If you override the JS components, rebuild and republish assets, not just clear the PHP cache.PATCH /api/users/{id}. If your integration hits the user endpoint as a regular user, expect a 403; use the settings flow or grant the appropriate permission group.flarum/nicknames on the same minor as flarum/core. Mixing a newer extension with an older core is the most common source of missing displayName or broken settings forms.How can I help you explore Laravel packages today?