In Flarum, Controller is just another name for a class that implements RequestHandlerInterface. Put simply, a controller must implement a handle method which receives a Request and must return a Response. Flarum includes zend-diactoros which contains Response implementations that you can return.

You can generate URLs to any of the defined routes using the Flarum\Http\UrlGenerator class. Inject an instance of this into your controller or view, and call the to method to select a route collection. Then, you can generate a URL to a route using the name you gave it when it was defined. You can pass an array of parameters as the second argument. Parameters will fill in matching URI segments, otherwise they will be appended as query params.

Adding routes to the frontend actually requires you to register them on both the frontend and the backend. This is because when your route is visited, the backend needs to know to serve up the frontend, and the frontend needs to know what to display on the page.

On the backend, instead of adding your frontend route via the Routes extender, you should use the Frontend extender's route method. This always assumes GET as the method, and accepts a route path and name as the first two arguments:

(newExtend\Frontend('forum'))->route('/users','acme.users')

Now when yourforum.com/users is visited, the forum frontend will be displayed. However, since the frontend doesn't yet know about the users route, the discussion list will still be rendered.

To register the route on the frontend, there is a Routes extender which works much like the backend one. Instead of a controller, however, you pass a component instance as the third argument:

To generate a URL to a route on the frontend, use the app.route method. This accepts two arguments: the route name, and a hash of parameters. Parameters will fill in matching URI segments, otherwise they will be appended as query params.

Whenever you visit a frontend route, the backend constructs a HTML document with the scaffolding necessary to boot up the frontend JavaScript application. You can easily modify this document to perform tasks like:

Changing the <title> of the page

Adding external JavaScript and CSS resources

Adding SEO content and <meta> tags

Adding data to the JavaScript payload (eg. to preload resources which are going to be rendered on the page immediately, thereby preventing an unnecessary request to the API)

You can make blanket changes to the frontend using the Frontend extender's content method. This accepts a closure which receives two parameters: a Flarum\Frontend\Document object which represents the HTML document that will be dispalyed, and the Request object.