# `Beamlet.Router`
[🔗](https://github.com/aaronrussell/beamlet/blob/v0.1.0/lib/beamlet/router.ex#L1)

The router your app forwards to, which serves the beamlet.

Add it as the last route in your router, at the root:

    forward "/", Beamlet.Router

Last, so your own routes win. At the root, because LiveView pages
match the full URL and break under a forward at a prefix. To serve
the routes agents mount under a path, set `:prefix` in
`Beamlet.Config` instead.

The beamlet keeps its own pages under `/beamlet`, where agents can
never mount a route:

* `/beamlet/mcp` - the MCP server (`Beamlet.MCP.Server`).
* `/beamlet` - the home page, behind the sign-in.
* `/beamlet/login` and `/beamlet/logout` - signing in and out.
* `/beamlet/authorize` and `/beamlet/token` - OAuth
  (`Beamlet.OAuth`).

It also answers the two OAuth documents under `/.well-known`. Every
other path goes to the routes agents mount, so `/` answers 404
until an agent builds something there.

## What your endpoint needs

Agent pages are LiveViews, so your endpoint needs what any LiveView
app has, plus a socket for the beamlet's own pages:

    socket "/beamlet/agent/live", Phoenix.LiveView.Socket,
      websocket: [connect_info: [session: @session_options]]

    socket "/beamlet/app/live", Phoenix.LiveView.Socket,
      websocket: [connect_info: [session: {Beamlet.Web.Auth, :session_options, []}]]

    plug Beamlet.Assets

    plug Plug.Parsers,
      parsers: [:urlencoded, :json],
      pass: ["*/*"],
      json_decoder: Phoenix.json_library()

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

* `/beamlet/agent/live` is the socket agent pages connect to, with your
  endpoint's session.
* `/beamlet/app/live` is the socket the beamlet's own pages connect
  to, with their own session.
* `Beamlet.Assets` serves the LiveView JavaScript and the
  beamlet's stylesheet. It goes before the parsers.
* `Plug.Parsers` leaves out multipart. It writes uploads to the
  system temp dir, where agent code cannot read them.
* `Plug.MethodOverride` lets agent forms reach their PUT, PATCH and
  DELETE routes.
* Behind a proxy that terminates TLS, add
  `plug Plug.RewriteOn, [:x_forwarded_proto]` before `Plug.Session`,
  so the session cookies are marked secure.

And in config:

    config :beamlet, web: [endpoint: MyAppWeb.Endpoint]

    config :my_app, MyAppWeb.Endpoint,
      pubsub_server: Beamlet.PubSub,
      render_errors: [
        formats: [html: Beamlet.Web.ErrorView, json: Beamlet.Web.ErrorView],
        layout: false
      ]

    config :phoenix, :filter_parameters,
      ["password", "code", "code_verifier", "refresh_token"]

`pubsub_server` lets agent pages subscribe through `Host.PubSub`.
`Beamlet.Web.ErrorView` is a plain error view, and your own works
too. The filtered parameters keep the sign-in's password and the
OAuth secrets out of the request log.

The standalone server's
[endpoint](https://github.com/aaronrussell/beamlet/blob/main/server/lib/beamlet_server/endpoint.ex)
is a worked example.

> #### Nothing may fetch the session before the forward {: .warning}
>
> The beamlet's pages swap in their own session as the request
> reaches this router. If a plug in your endpoint or router fetches
> the session first, the owner's sign-in lands in your endpoint's
> session, which agent pages can read and write.

# `call`

Callback invoked by Plug on every request.

# `formatted_routes`

# `init`

Callback required by Plug that initializes the router
for serving web requests.

# `verified_route?`

---

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