Work In Progress

This book is currently work in progress. Some sections are not yet written. Thank you for your understanding!

Joomla 3 vs Joomla 4

In Joomla 3 we would create a router as a router.php file in the root of our component's frontend, e.g. components/com_example/router.php. That file had two ways to implement a router:

  • Two separate functions whose names consisted of the name of the component without the com_ prefix and the suffixes BuildRoute and ParseRoute, e.g. exampleBuildRoute and exampleParseRoute. This was the very old way which was deprecated since Joomla 3.3 released in 2014.

  • As a class extending JComponentRouterBase (renamed to Joomla\CMS\Component\Router\RouterBase in later Joomla versions) or, more usually, JComponentRouterView (introduced in Joomla 3.5 and renamed to Joomla\CMS\Component\Router\RouterView in later Joomla versions).

If you are using the former method you have a lot of work ahead of you to convert it to a Joomla 4 compatible router. If you are using the latter method you are virtually ready, with minimal changes!

In Joomla 4 the router is implemented as the class Service\Router in the frontend part of our component. So, with a component com_example that has a namespace prefix Acme\Component\Example that would be the class Acme\Component\Example\Site\Service\Router in the file components/com_example/src/Service/Router.php. That class needs to extend from Joomla\CMS\Component\Router\RouterBase or, more typically Joomla\CMS\Component\Router\RouterView, just like in Joomla 3.5[2] and later versions.

There is one more difference in Joomla 4 and later versions. By default, the component does not know that it needs to use a router.

To understand what and why we need to do, let's go backwards. Joomla only knows it needs to use a router factory when the component's extension class implements the \Joomla\CMS\Component\Router\RouterServiceInterface. When this is the case, Joomla knows that it can ask the extension class to return a Router Factory object using the createRouter method defined in said interface. The component's extension class does not know how to find the router factory object; it is injected into it by the component service provider (services/provider.php). In its turn, it asks the component's DI Container for that Router Factory object. The DI Container will only know how to get a Router Factory object if we register a Router Factory service provider in the service provider (services/provider.php).

Unraveling these chained dependencies we see that we need to make changes in just two files.

Your component's extension class must implement the \Joomla\CMS\Component\Router\RouterServiceInterface interface. The easiest way to provide its implementation is having it use the \Joomla\CMS\Component\Router\RouterServiceTrait trait.

That trait requires your component service provider (e.g. administrator/components/com_example/services/provider.php) to do two things. First, it needs to register a Router Factory service provider before trying to create the component object:

  new \Joomla\CMS\Extension\Service\Provider\RouterFactory

The \Joomla\CMS\Extension\Service\Provider\RouterFactory class is the default Joomla implementation of a component router factory. It needs exactly one configuration parameter in its constructor, the namespace of your component without the Site or Administrator suffix.

Then, after having created our component extension class' object, we need to inject the Router Factory object into it:

  function (Container $container) {
    $component = new ExampleComponent(

    // ... other initialisation goes here ...

    // Inject the router factory object

While it looks a bit verbose, it accomplishes two things. First, it's not possible to be surprised by Joomla magically implementing a feature in your component you did not expect. Second, in the case of a router, it allows us to push dependencies (services) into our router object.

[2] The entire concept of routing using the RouterView has not changed since Joomla 3.5 which was released in 2016. You see, at this point in time development of Joomla 4 had already started and Joomla introduced the new routing to help developers migrate their extensions to the new router before Joomla 4 is released.