Writing a Flarum Extension: Building a Custom Field

Flarum is incredibly fast, extensible, free and open-source forum software. It has been in development since 2014 and is nearing the end of its beta phase.

In this tutorial, we’ll go through the process of adding a custom field to a user account. This custom field will be settable from a user’s profile page by the user only, but also manually editable by an administrator. The full and final source code of this extension is on GitHub.

🙏 Huge thanks to @askvortsov for review and assistance in doing this The Right Way™.

What We’re Adding

We’ll allow users to add their Web3 address into their profile. A Web3 address is a user’s cryptographic identity in the Web3 ecosystem – the public part of a public-private keypair (like SSH) representing one’s blockchain-compatible account.

Note ℹ: the Web3 ecosystem is a new internet of decentralized hosting, self-owned data, and censorship-resistant communication. For a primer on Web3, please see this 15 minute talk at FOSDEM.

Even if you’re not interested in Web3, this tutorial will be useful. This first part of the tutorial will show you how to build a custom field for a user, and the second part will add the actual Web3 address in a cryptographically secure way.


We assume you have NodeJS installed and on a recent enough version (12.16+ is OK), and Composer available globally. For your sanity, we also recommend using Yarn instead of npm. PHP, MySQL, and other requirements for Flarum are assumed to be present and running properly.

In the examples below, we’re hosting the local Flarum copy at ubikforum.test, which some screenshots might reflect.

Please also make sure that your forum is in debug mode by setting the appropriate value in config.php:

<?php return array(
    'debug' => true,
    'database' => // ...

New Extension

We start a new extension by running the Friends of Flarum boilerplate wizard inside a newly created packages folder in our local Flarum installation’s root folder:

# cd into your flarum folder
mkdir packages & cd packages
npx @friendsofflarum/create-flarum-extension web3address

Important ⚠: remember to follow best deployment practices and ignore the packages folder if you’re pushing this Flarum folder to a repo from which you’re deploying your live version.

Fill out the inputs provided by the wizard:

✔ Admin CSS & JS … no
✔ Forum CSS & JS … yes
✔ Locale … yes
✔ Javascript … yes
✔ CSS … yes

Note ℹ: you’ll want to set Admin CSS & JS to yes if you have plans to work with settings and/or permissions, like letting only some people modify their web3address attribute or similar. In this case, we don’t need it.

Keep in mind that, due to a bug, the generator doesn’t support numbers in the package name or namespace. As such, it’s best to rename those values after the generation is complete. (For example, you can’t use web3address as the name, but blockchain is fine.)

We also need to compile the JavaScript. It’s best to leave it running in watch mode, so that it’s automatically recompiled on file changes and you can quickly check changes while developing:

cd packages/web3address
cd js
yarn && yarn dev

Note ℹ: you’ll want to leave this running in a terminal tab and execute the rest of the commands in another tab. The dev command activates an always-on task that will occupy the current terminal session.

We then install our newly created extension:

composer config repositories.0 path "packages/*"
composer require swader/blockchain @dev

The first line will tell Composer that it should look for packages we install in the packages subfolder, and, if it doesn’t find them, to default to Packagist.org.

The second line installs our newly created extension. Once it’s in, we can load our forum’s admin interface, activate the extension, and check the console on the forum’s front end for a “Hello world” message. If it’s there, the new extension works.

Adding an extension: add web3 address, Approval, BBCode

Hello, forum message in the developer console


When building extensions, you’re always extending the raw Flarum underneath. These extensions are defined in your extension’s extend.php file with various extenders being “categories” of possible extension points you can hook into. We’ll modify this file later.

Keep in mind that the forum itself has an extend.php file in its root folder as well. This file is useful for minor, root-level extensions that your users can do on your instance of Flarum without having to write a full extension around the functionality. If you want to share what you’ve built with others, or distribute it to alternative copies of Flarum, an extension is the way to go.

The extend.php file currently looks like this:

namespace SwaderWeb3Address;

use FlarumExtend;

return [
    (new ExtendFrontend('forum'))
        ->js(__DIR__ . '/js/dist/forum.js')
        ->css(__DIR__ . '/resources/less/forum.less'),

    new ExtendLocales(__DIR__ . '/resources/locale')

If you were extending the admin UI as well, there would be another Frontend block referencing admin instead of forum. As it stands, we’re only adding new JS and styles to the forum’s front end and, optionally, localizing our extension’s UI elements, so these are the parts that get extended.

This file is where we’ll define alternative routes and some listeners, as you’ll see later.

Continue reading
Writing a Flarum Extension: Building a Custom Field
on SitePoint.