GreXXL huseyinfiliz That's really great indeed, thank you both!
I tested this on my dev server and it worked great. It's a bit scary at first because when you install the new extension it defaults to off, so the landing page renders a blank body. Once enabled, it works!
On my production server I had another scare where initially I got this error:
[2026-02-21 07:04:22] flarum.ERROR: ReflectionException: Class "FoF\Categories\Content\Categories" does not exist in /var/www/html/vendor/illuminate/container/Container.php:877
Stack trace:
#0 /var/www/html/vendor/illuminate/container/Container.php(877): ReflectionClass->__construct()
#1 /var/www/html/vendor/illuminate/container/Container.php(758): Illuminate\Container\Container->build()
#2 /var/www/html/vendor/illuminate/container/Container.php(694): Illuminate\Container\Container->resolve()
#3 /var/www/html/vendor/flarum/core/src/Http/RouteHandlerFactory.php(55): Illuminate\Container\Container->make()
#4 /var/www/html/vendor/illuminate/container/BoundMethod.php(36): Flarum\Http\RouteHandlerFactory->Flarum\Http{closure}()
#5 /var/www/html/vendor/illuminate/container/Util.php(40): Illuminate\Container\BoundMethod::Illuminate\Container{closure}()
#6 /var/www/html/vendor/illuminate/container/BoundMethod.php(81): Illuminate\Container\Util::unwrapIfClosure()
#7 /var/www/html/vendor/illuminate/container/BoundMethod.php(35): Illuminate\Container\BoundMethod::callBoundMethod()
#8 /var/www/html/vendor/illuminate/container/Container.php(653): Illuminate\Container\BoundMethod::call()
#9 /var/www/html/vendor/flarum/core/src/Http/RouteHandlerFactory.php(75): Illuminate\Container\Container->call()
#10 /var/www/html/vendor/flarum/core/src/Http/RouteHandlerFactory.php(37): Flarum\Http\RouteHandlerFactory->resolveController()
#11 /var/www/html/vendor/flarum/core/src/Http/Middleware/ExecuteRoute.php(27): Flarum\Http\RouteHandlerFactory->Flarum\Http{closure}()
#12 /var/www/html/vendor/laminas/laminas-stratigility/src/Next.php(49): Flarum\Http\Middleware\ExecuteRoute->process()
#13 /var/www/html/vendor/fof/anti-spam/src/Middleware/CheckLoginMiddleware.php(86): Laminas\Stratigility\Next->handle()
#14 /var/www/html/vendor/laminas/laminas-stratigility/src/Next.php(49): FoF\AntiSpam\Middleware\CheckLoginMiddleware->process()
#15 /var/www/html/vendor/fof/byobu/src/Middleware/GuestAccessToPrivateRoutePrevention.php(32): Laminas\Stratigility\Next->handle()
#16 /var/www/html/vendor/laminas/laminas-stratigility/src/Next.php(49): FoF\Byobu\Middleware\GuestAccessToPrivateRoutePrevention->process()
#17 /var/www/html/vendor/flarum/core/src/Http/Middleware/ContentTypeOptionsHeader.php(21): Laminas\Stratigility\Next->handle()
#18 /var/www/html/vendor/laminas/laminas-stratigility/src/Next.php(49): Flarum\Http\Middleware\ContentTypeOptionsHeader->process()
#19 /var/www/html/vendor/flarum/core/src/Http/Middleware/ReferrerPolicyHeader.php(30): Laminas\Stratigility\Next->handle()
#20 /var/www/html/vendor/laminas/laminas-stratigility/src/Next.php(49): Flarum\Http\Middleware\ReferrerPolicyHeader->process()
#21 /var/www/html/vendor/flarum/core/src/Http/Middleware/FlarumPromotionHeader.php(30): Laminas\Stratigility\Next->handle()
#22 /var/www/html/vendor/laminas/laminas-stratigility/src/Next.php(49): Flarum\Http\Middleware\FlarumPromotionHeader->process()
#23 /var/www/html/vendor/flarum/core/src/Http/Middleware/ShareErrorsFromSession.php(57): Laminas\Stratigility\Next->handle()
#24 /var/www/html/vendor/laminas/laminas-stratigility/src/Next.php(49): Flarum\Http\Middleware\ShareErrorsFromSession->process()
#25 /var/www/html/vendor/flarum/core/src/Http/Middleware/CheckCsrfToken.php(36): Laminas\Stratigility\Next->handle()
#26 /var/www/html/vendor/laminas/laminas-stratigility/src/Next.php(49): Flarum\Http\Middleware\CheckCsrfToken->process()
#27 /var/www/html/vendor/flarum/core/src/Http/Middleware/ResolveRoute.php(69): Laminas\Stratigility\Next->handle()
#28 /var/www/html/vendor/laminas/laminas-stratigility/src/Next.php(49): Flarum\Http\Middleware\ResolveRoute->process()
#29 /var/www/html/vendor/flamarkt/backoffice/src/Middleware/SubForumRouter.php(37): Laminas\Stratigility\Next->handle()
#30 /var/www/html/vendor/laminas/laminas-stratigility/src/Next.php(49): Flamarkt\Backoffice\Middleware\SubForumRouter->process()
#31 /var/www/html/vendor/flarum/core/src/Http/Middleware/SetLocale.php(51): Laminas\Stratigility\Next->handle()
#32 /var/www/html/vendor/laminas/laminas-stratigility/src/Next.php(49): Flarum\Http\Middleware\SetLocale->process()
#33 /var/www/html/vendor/flarum/core/src/Http/Middleware/AuthenticateWithSession.php(31): Laminas\Stratigility\Next->handle()
#34 /var/www/html/vendor/laminas/laminas-stratigility/src/Next.php(49): Flarum\Http\Middleware\AuthenticateWithSession->process()
#35 /var/www/html/vendor/flarum/core/src/Http/Middleware/RememberFromCookie.php(63): Laminas\Stratigility\Next->handle()
#36 /var/www/html/vendor/laminas/laminas-stratigility/src/Next.php(49): Flarum\Http\Middleware\RememberFromCookie->process()
#37 /var/www/html/vendor/flarum/core/src/Http/Middleware/StartSession.php(61): Laminas\Stratigility\Next->handle()
#38 /var/www/html/vendor/laminas/laminas-stratigility/src/Next.php(49): Flarum\Http\Middleware\StartSession->process()
#39 /var/www/html/vendor/flarum/core/src/Http/Middleware/CollectGarbage.php(46): Laminas\Stratigility\Next->handle()
#40 /var/www/html/vendor/laminas/laminas-stratigility/src/Next.php(49): Flarum\Http\Middleware\CollectGarbage->process()
#41 /var/www/html/vendor/flarum/core/src/Http/Middleware/ParseJsonBody.php(28): Laminas\Stratigility\Next->handle()
#42 /var/www/html/vendor/laminas/laminas-stratigility/src/Next.php(49): Flarum\Http\Middleware\ParseJsonBody->process()
#43 /var/www/html/vendor/migratetoflarum/canonical/src/Middlewares/CanonicalRedirectMiddleware.php(49): Laminas\Stratigility\Next->handle()
#44 /var/www/html/vendor/laminas/laminas-stratigility/src/Next.php(49): MigrateToFlarum\Canonical\Middlewares\CanonicalRedirectMiddleware->process()
#45 /var/www/html/vendor/flarum/core/src/Http/Middleware/HandleErrors.php(57): Laminas\Stratigility\Next->handle()
#46 /var/www/html/vendor/laminas/laminas-stratigility/src/Next.php(49): Flarum\Http\Middleware\HandleErrors->process()
#47 /var/www/html/vendor/flarum/core/src/Http/Middleware/InjectActorReference.php(25): Laminas\Stratigility\Next->handle()
#48 /var/www/html/vendor/laminas/laminas-stratigility/src/Next.php(49): Flarum\Http\Middleware\InjectActorReference->process()
#49 /var/www/html/vendor/laminas/laminas-stratigility/src/MiddlewarePipe.php(81): Laminas\Stratigility\Next->handle()
#50 /var/www/html/vendor/middlewares/request-handler/src/RequestHandler.php(84): Laminas\Stratigility\MiddlewarePipe->process()
#51 /var/www/html/vendor/laminas/laminas-stratigility/src/Next.php(49): Middlewares\RequestHandler->process()
#52 /var/www/html/vendor/middlewares/base-path-router/src/BasePathRouter.php(97): Laminas\Stratigility\Next->handle()
#53 /var/www/html/vendor/laminas/laminas-stratigility/src/Next.php(49): Middlewares\BasePathRouter->process()
#54 /var/www/html/vendor/laminas/laminas-stratigility/src/Middleware/OriginalMessages.php(36): Laminas\Stratigility\Next->handle()
#55 /var/www/html/vendor/laminas/laminas-stratigility/src/Next.php(49): Laminas\Stratigility\Middleware\OriginalMessages->process()
#56 /var/www/html/vendor/middlewares/base-path/src/BasePath.php(73): Laminas\Stratigility\Next->handle()
#57 /var/www/html/vendor/laminas/laminas-stratigility/src/Next.php(49): Middlewares\BasePath->process()
#58 /var/www/html/vendor/flarum/core/src/Http/Middleware/ProcessIp.php(24): Laminas\Stratigility\Next->handle()
#59 /var/www/html/vendor/laminas/laminas-stratigility/src/Next.php(49): Flarum\Http\Middleware\ProcessIp->process()
#60 /var/www/html/vendor/laminas/laminas-stratigility/src/MiddlewarePipe.php(81): Laminas\Stratigility\Next->handle()
#61 /var/www/html/vendor/laminas/laminas-stratigility/src/MiddlewarePipe.php(70): Laminas\Stratigility\MiddlewarePipe->process()
#62 /var/www/html/vendor/laminas/laminas-httphandlerrunner/src/RequestHandlerRunner.php(73): Laminas\Stratigility\MiddlewarePipe->handle()
#63 /var/www/html/vendor/flarum/core/src/Http/Server.php(45): Laminas\HttpHandlerRunner\RequestHandlerRunner->run()
#64 /var/www/html/public/index.php(26): Flarum\Http\Server->listen()
#65 {main}
This is not the first time this has happened to me, so I know it's not specific to this extension. Restarting the server worked. Not sure why this happens though. Please enlighten me if you know!
Then I ran into another issue. On the original extension, I had customized some of the text so that Categories is Forums instead. I had used FoF Linguist for this. Unfortunately, that customization doesn't carry over, but I was able to find the equivalent strings that needed updating.
PianoTell is now running FriendsOfFlarum Categories, thank you!
It looks I should see if the other extensions need to be upgraded to their FoF equivalents.