Getting Started

Set up PhoenixPrerender in 5 minutes

prerendered

Prerendered under the /docs scope. Generated file: docs/getting-started/index.html

1

Add the Dependency

# mix.exs
defp deps do
  [
    {:phoenix_prerender, "~> 0.1.1"}
  ]
end
2

Mark Routes

Import the macro and wrap routes you want to prerender. Dead views are prerendered by default. LiveView routes require explicit metadata to control serving behavior:

import PhoenixPrerender

scope "/", MyAppWeb do
  pipe_through :browser

  prerender do
    # Dead views: prerendered and served to everyone
    get "/about", PageController, :about
    get "/pricing", PageController, :pricing

    # LiveView: not prerendered (just live) unless metadata is set
    live "/changelog", ChangelogLive

    # LiveView: prerendered HTML served to bots for SEO
    live "/status", StatusLive, :index,
      metadata: %{prerender: :bots_only}

    # LiveView: prerendered for everyone + ISR regeneration
    live "/dashboard", DashboardLive, :index,
      metadata: %{prerender: :always, isr: true}
  end
end

Or use the explicit syntax for dead views: get "/about", PageController, :about, metadata: %{prerender: true}

3

Add the Plug

Add PhoenixPrerender.Plug to your endpoint, before the router. Pass session_options if you use prerender: :always on any LiveView route:

# lib/my_app_web/endpoint.ex
@session_options [
  store: :cookie,
  key: "_my_app_key",
  signing_salt: "..."
]

plug Plug.Static, ...

# Serve prerendered pages (session_options enables CSRF swap for :always routes)
plug PhoenixPrerender.Plug, session_options: @session_options

plug Plug.Session, @session_options
plug MyAppWeb.Router
4

Configure

# config/prod.exs
config :phoenix_prerender,
  enabled: true
5

Generate

$ mix phoenix.prerender

PhoenixPrerender: Discovering routes from MyAppWeb.Router...
PhoenixPrerender: Generated 3 pages to priv/static/prerendered

Options: --path /about, --style file, --concurrency 4