# `Xenia.Page`
[🔗](https://github.com/uzaydurdu/xenia/blob/v0.1.1/lib/xenia/app/page.ex#L1)

A page in a Xenia app folder: the `page.ex` that makes its folder a route.

A standalone page is an ordinary LiveView. `use Xenia.Page` after your app's
`use MyAppWeb, :live_view` adds two things:

  * its `render/1` is drawn inside the layouts of its folder and above,
    outermost first, with the persistent part of each layout that has a
    `persistent.ex` (`Xenia.Layout`)
  * those layouts' `on_mount` hooks run before its `mount/3`

```elixir
# app/(auth)/dashboard/page.ex  →  /dashboard
defmodule MyAppWeb.DashboardPage do
  use MyAppWeb, :live_view
  use Xenia.Page

  def mount(_params, _session, socket), do: {:ok, assign(socket, alerts: [])}

  def render(assigns) do
    ~H"<h1>Dashboard</h1>"
  end
end
```

Under a `live.ex` (see `Xenia.Live`), a page is rendered by that shared
LiveView instead: only its `render/1` is used, with the owner's assigns. A
page there can `use Xenia.Page` too, or be any module with `render/1`.

Which layouts apply comes from the router: `xenia_routes` records them for
every page. A page served by a hand-written route has none.

## Metadata and the sitemap

A page can define `metadata/1`, for its title, description and social
tags (see `Xenia.Metadata`), and `sitemap/0`, for `Xenia.Sitemap`:

    def metadata(assigns), do: %{title: assigns.post.title}

    # A page with parameters is listed only with the params you give:
    def sitemap, do: for(post <- Blog.list_posts(), do: %{slug: post.slug})

# `layouts`

```elixir
@spec layouts(Phoenix.LiveView.Socket.t(), atom()) :: [module()]
```

The layout modules that apply to the page `socket` is showing, outermost
first, as recorded by `xenia_routes`. Empty for a page served by a
hand-written route.

For a shared LiveView, the page is its `live_action`; for a standalone page,
the LiveView itself.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
