When we think of Flarum's frontend, the first thing that comes to mind is the dynamic, JS-powered SPA. However, before this frontend is rendered by JS, the first thing your browser receives is a simple, server-generated HTML page. This generally includes:
- A simple no-js view, so that the forum is remotely usable even if something breaks with the JS SPA.
- SEO metadata, since search engines gather the majority of their data from the initial returned HTML.
- A bit of code that starts up the JS SPA.
- An initial payload of data, so that users don't need to wait for a spinner right after opening a page.
Flarum responds to requests based on routing config, so the first place we look is the forum routes.php, where core's forum routes are defined. We see that for all "frontend" routes (ie those you can type into your browser bar and visit), we use $routes->toForum(Content\Something::class)
, which in turn uses RouteHandlerFactory::toFrontend
.
RouteHandlerFactory::toFrontend
does several things:
- It resolves a
frontend
object
- It applies the
Content\Something::class
argument (back from when toForum
was called in routes.php) to the frontend object
- It returns the
frontend
object wrapped in Flarum\Frontend\Controller
, which calls the frontend
's render
method, and returns the result wrapped in HTML.
The bulk of interesting things happen with the frontend
object, so let's focus on that. It's an instance of Flarum\Frontend\Frontend.php
, which is essentially a wrapper around Flarum\Frontend/Document.php
. You can think of Document
as a util for building an HTML response: you can give it various info (see the list at the top of the page), and it'll put everything together into HTML when its render
method is called.
How does that information actually get into the document? Well, that's where Content\Something::class
comes in. A content callback is essentially a function that takes a document
, and adds some stuff onto it. Some contents are applied to every document, when a frontend/document is first instantiated. The other major source of content is route config: for example, in the forum routes config file many routes have content just for that route. This is where things like the page title, the initial payload, and no-js HTML are configured.