docs-pages.md
Pages are specialized components that serve as entry points for different routes in your Hologram application. Together with regular components, they form the fundamental building blocks of Hologram applications. They inherit all the capabilities of components, including templates, state management, actions, commands, and event handling. For detailed information about these shared features, see the Components documentation.
While pages are built on top of components, they have some unique characteristics:
route/1 macrolayout/1 or layout/2 macro, which serves as the root of the component tree and wraps the page's content (see Layouts for more information)init/3, unlike regular components which can be initialized on either client or serverinit/3 function receives URL parameters (params) instead of component props (props)Every page is fully rendered to HTML on the server on first load, then becomes interactive on the client. Because the browser (and any crawler) receives complete, server-rendered markup, Hologram pages are SEO-friendly and fast to first paint out of the box, with no extra configuration.
This is why a page's init/3 always runs on the server: it produces the state used to render the initial HTML. Once the page is mounted in the browser, client-side state takes over and subsequent interactions happen without full page reloads (see Navigation for how transitions between pages work).
Here's a simple page implementation:
defmodule MyApp.GreetingPage do
use Hologram.Page
route "/hello/:username"
layout MyApp.MainLayout
def init(params, component, _server) do
put_state(component, :username, params.username)
end
def template do
~HOLO"""
<div>Hello, {@username}!</div>
"""
end
end
You can chain actions that will be executed when the page is mounted on the client:
def init(_params, component, _server) do
put_action(component, :load_user_data)
end
The init/3 function is optional. If you don't need to initialize state or perform any preparation, you can omit it entirely - Hologram provides a default implementation that simply returns the Component and Server structs unchanged.
Server-side middleware attached to the page runs before init/3, so you can authenticate, authorize, or enrich the request before the page renders.
Pages must define their URL route using the route/1 macro.
Routes can be static:
route "/products"
or contain dynamic parameters:
route "/users/:username/posts/:post_id/comments"
For routes with parameters, use the param/2 macro to specify how string parameters should be converted:
param :username, :string
param :post_id, :integer
Supported parameter types:
:atom - converts to atom:float - converts to float:integer - converts to integer:string - keeps the parameter as stringHologram's router uses a search tree rather than ordered routing (like Phoenix or Rails). Static segments are always prioritized over parameterized ones automatically - so /users will always match before /:username, regardless of the order pages are defined. This eliminates a whole class of route shadowing bugs that are common in ordered routers, where adding a route in the wrong position can silently break another.
The tradeoff is that you can't have two ambiguous parameterized routes at the same level (e.g. /:username and /:post_slug). In practice, this is a design smell in any framework - the fix is always to give them distinct prefixes, such as /users/:username and /posts/:post_slug.
The page is always assigned a component ID (cid) of "page". This is important to remember when targeting actions or commands at the page.
Sponsored by
Previous
Next