Per-page metadata for Phoenix LiveView apps: breadcrumbs, active-link state, SEO meta tag rendering.
Setup
In your project's PageMeta module:
defmodule MyAppWeb.PageMeta do
use PhoenixPageMeta
@enforce_keys [:title, :path]
defstruct [
:title,
:path,
:breadcrumb_title,
:parent,
:description,
:og_image,
:json_ld,
:canonical_path,
:icon,
:skip_breadcrumb,
og_type: "website",
noindex: false,
supported_locales: [:en, :es]
]
endThat's it. No config.exs entry. The macro provides default implementations
of base_url/0 (auto-detected from the module's namespace, e.g.
MyAppWeb.PageMeta → MyAppWeb.Endpoint.url()) and lang_path/2
(locale-prefix swap on :path). Both are defoverridable if you need a
different scheme.
use options
:base_url— accepts a string ("https://example.com") or a 0-arity function capture (&MyAppWeb.Endpoint.url/0). When omitted, the macro guesses the Endpoint module from your PageMeta's namespace.
In LiveViews
In MyAppWeb.live_view/0:
def live_view do
quote do
use Phoenix.LiveView, layout: ...
@behaviour PhoenixPageMeta.LiveView
import PhoenixPageMeta.LiveView, only: [assign_page_meta: 1]
end
endIn each LiveView:
defmodule MyAppWeb.SomeLive do
use MyAppWeb, :live_view
@impl PhoenixPageMeta.LiveView
def page_meta(_socket, _action) do
%MyAppWeb.PageMeta{title: "Hello", path: "/hello"}
end
def mount(_params, _session, socket) do
{:ok, assign_page_meta(socket)}
end
endSee PhoenixPageMeta.Breadcrumb, PhoenixPageMeta.Components.Breadcrumbs,
PhoenixPageMeta.Components.MetaTags, PhoenixPageMeta.Site, and
PhoenixPageMeta.LiveView.
Summary
Functions
Injects the PhoenixPageMeta wiring into a project PageMeta module.
Returns true if the given link path matches the current page or one of its ancestor paths.
Functions
Injects the PhoenixPageMeta wiring into a project PageMeta module.
Adds @behaviour PhoenixPageMeta.Site, default implementations of
base_url/0 and lang_path/2 (both defoverridable), wrappers for
breadcrumbs/1 and active?/2,3 that match the project struct, and an
@after_compile hook that validates the struct has the required fields.
Returns true if the given link path matches the current page or one of its ancestor paths.
Options
:exact— whentrue, only matches the current page exactly. Defaultfalse.:query— whentrue, query strings are part of the comparison. Whenfalse(default), they are stripped from both sides before matching.
Matching rules
Without :exact, a link is active if its path equals the current path or is
a prefix followed by /. So /locations matches /locations and
/locations/123, but not /location-foo.
Most projects call this via the project module's wrapper (e.g.
MyAppWeb.PageMeta.active?/2,3), which restricts the input type via
%MyAppWeb.PageMeta{} pattern. The lib-level function accepts any struct.