The router your app forwards to, which serves the beamlet.
Add it as the last route in your router, at the root:
forward "/", Beamlet.RouterLast, 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/loginand/beamlet/logout- signing in and out./beamlet/authorizeand/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/liveis the socket agent pages connect to, with your endpoint's session./beamlet/app/liveis the socket the beamlet's own pages connect to, with their own session.Beamlet.Assetsserves the LiveView JavaScript and the beamlet's stylesheet. It goes before the parsers.Plug.Parsersleaves out multipart. It writes uploads to the system temp dir, where agent code cannot read them.Plug.MethodOverridelets agent forms reach their PUT, PATCH and DELETE routes.- Behind a proxy that terminates TLS, add
plug Plug.RewriteOn, [:x_forwarded_proto]beforePlug.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 is a worked example.
Nothing may fetch the session before the forward
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.
Summary
Functions
Callback invoked by Plug on every request.
Callback implementation for Phoenix.VerifiedRoutes.formatted_routes/1.
Callback required by Plug that initializes the router for serving web requests.
Callback implementation for Phoenix.VerifiedRoutes.verified_route?/2.
Functions
Callback invoked by Plug on every request.
Callback implementation for Phoenix.VerifiedRoutes.formatted_routes/1.
Callback required by Plug that initializes the router for serving web requests.
Callback implementation for Phoenix.VerifiedRoutes.verified_route?/2.