Oban.Web.Router (Oban Web v2.10.4)

Provides mount points for the Web dashboard with customization.

Customizing with a Resolver Callback Module

Implementing a Oban.Web.Resolver callback module allows you to customize the dashboard per-user, i.e. setting access controls or the default refresh rate.

As a simple example, let's define a module that makes the dashboard read only:

defmodule MyApp.Resolver do
  @behaviour Oban.Web.Resolver

  @impl true
  def resolve_access(_user), do: :read_only

Then specify MyApp.Resolver as your resolver:

scope "/" do
  pipe_through :browser

  oban_dashboard "/oban", resolver: MyApp.Resolver

See the Oban.Web.Resolver docs for more details.

Running Multiple Dashboards

Applications that run multiple Oban instances can mount a dashboard for each instance. Set the mounted dashboard's :oban_name to match the corresponding supervision tree's name. For example, given two configured Oban instances, Oban and MyAdmin.Oban:

config :my_app, Oban,
  repo: MyApp.Repo,
  name: Oban,

config :my_admin, Oban,
  repo: MyAdmin.Repo,
  name: MyAdmin.Oban,

You can then mount both dashboards in your router:

scope "/" do
  pipe_through :browser

  oban_dashboard "/oban", oban_name: Oban, as: :oban_dashboard
  oban_dashboard "/admin/oban", oban_name: MyAdmin.Oban, as: :oban_admin_dashboard

Note that the default name is Oban, setting oban_name: Oban in the example above was purely for demonstration purposes.

On Mount Hooks

You can provide a list of hooks to attach to the dashboard's mount lifecycle. Additional hooks are prepended before Oban Web's own Authentication. For example, to run a user-fetching hook and an activation checking hook before mount:

scope "/" do
  pipe_through :browser

  oban_dashboard "/oban", on_mount: [MyApp.UserHook, MyApp.ActivatedHook]

Customizing the Socket Connection

Applications that use a live socket other than "/live" can override the default socket path in the router. For example, if your live socket is hosted at /oban_live:

socket "/oban_live", Phoenix.LiveView.Socket

scope "/" do
  pipe_through :browser

  oban_dashboard "/oban", socket_path: "/oban_live"

If your application is hosted in an environment that doesn't support websockets you can use longpolling as an alternate transport. To start, make sure that your live socket is configured for longpolling:

socket "/live", Phoenix.LiveView.Socket,
  longpoll: [connect_info: [session: @session_options], log: false]

Then specify "longpoll" as your transport:

scope "/" do
  pipe_through :browser

  oban_dashboard "/oban", transport: "longpoll"

Content Security Policy

To secure the dashboard, or comply with an existing CSP within your application, you can specify nonce keys for images, scripts and styles.

You'll configure the CSP nonce assign key in your router, where the dashboard is mounted. For example, to use a single nonce for all three asset types:

oban_dashboard("/oban", csp_nonce_assign_key: :my_csp_nonce)

That instructs the dashboard to extract a generated nonce from the assigns map on the plug connection, at the :my_csp_nonce key.

Instead, you can specify different keys for each asset type:

  csp_nonce_assign_key: %{
    img: :img_csp_nonce,
    style: :style_csp_nonce,
    script: :script_csp_nonce



Defines an oban dashboard route.


Link to this macro

oban_dashboard(path, opts \\ [])


Defines an oban dashboard route.

It requires a path where to mount the dashboard at and allows options to customize routing.


  • :oban_name — name of the Oban instance the dashboard will use for configuration and notifications, defaults to Oban

  • :resolver — an Oban.Web.Resolver implementation used to customize the dashboard's functionality.

  • :socket_path — a phoenix socket path for live communication, defaults to "/live".

  • :transport — a phoenix socket transport, either "websocket" or "longpoll", defaults to "websocket".

  • :csp_nonce_assign_key — CSP (Content Security Policy) keys used to authenticate image, style, and script assets by pulling a generated nonce out of the connection's assigns map. May be nil, a single atom, or a map of atoms. Defaults to nil.


Mount an oban dashboard at the path "/oban":

defmodule MyAppWeb.Router do
  use Phoenix.Router

  import Oban.Web.Router

  scope "/", MyAppWeb do
    pipe_through [:browser]

    oban_dashboard "/oban"