# Customizing the Account Switcher The `AshMultiAccount.Phoenix.Components.account_switcher` component is intentionally unstyled — it provides data and URLs through slots, and you control all HTML and CSS. This topic covers common customization patterns. ## Basic Structure The component accepts two slots: - **`:account`** — rendered once per account (primary + all linked). Receives account data via `:let`. - **`:add_account`** — rendered once at the end. Receives the add-account URL via `:let`. ```heex <:account :let={account}> <:add_account :let={url}> ``` ## Slot Data Reference Each `:account` slot receives a map: ```elixir %{ user: %MyApp.Accounts.User{...}, # user struct with display_fields loaded current?: true | false, # is this the active account? primary?: true | false, # is this the primary account? switch_url: "/link/switch_to/abc" # URL to switch to this account } ``` The `:add_account` slot receives a URL string like `"/sign-in?return_to=%2Flink%2Fp%2Fabc-123"`. ## Minimal Example A simple list with no framework-specific styling: ```heex <:account :let={account}>
{account.user.name} (you) <.link :if={!account.current?} href={account.switch_url}> {account.user.name} — Switch
<:add_account :let={url}> <.link href={url}>+ Add another account
``` ## Dropdown Menu Example A dropdown menu using Tailwind CSS (adapted from the demo app): ```heex ``` With a helper component: ```elixir defp account_menu(assigns) do ~H""" <:account :let={account}> <%= if account.current? do %>
  • {account.user.name || account.user.email} {account.user.email}
    Active
  • <% else %>
  • <.link href={account.switch_url} class="flex items-center gap-3">
    {account.user.name || account.user.email} {account.user.email}
  • <% end %>
    <:add_account :let={url}>
  • <.link href={url}>Add another account
  • """ end ``` ## Custom Paths Override the default URL paths via component attributes: ```heex ... ``` These must match the paths defined in your router's `multi_account_routes/3` call: ```elixir multi_account_routes MultiAccountController, MyApp.Accounts.User, link_path: "/accounts/link/:primary_user_id", switch_path: "/accounts/switch/:user_id" ``` ## Display Fields The `display_fields` option on your User resource controls which fields are loaded and available on `account.user` in the slot: ```elixir multi_account do display_fields [:name, :email, :avatar_url] end ``` These fields are loaded by the LiveView hook, the `LoadMultiAccount` plug, and the `get_linked_accounts` preparation, so they're available when rendering the switcher. ## Showing Account Status Use `account.primary?` to indicate which account owns the session: ```heex <:account :let={account}>
    {account.user.name} (primary) (active)
    ``` ## Wrapping in Your Own Component For reuse across layouts, wrap the switcher in a function component: ```elixir defmodule MyAppWeb.Components.AccountSwitcher do use Phoenix.Component attr :current_user, :map, required: true attr :primary_user, :map, default: nil def account_switcher(assigns) do ~H"""
    <:account :let={account}> <%!-- your custom rendering --%> <:add_account :let={url}> <%!-- your custom rendering --%>
    """ end end ``` Then use it anywhere: ```heex ``` ## Using in Controller Templates The account switcher is a standard `Phoenix.Component` and works identically in both LiveView and controller-rendered templates. The only requirement is that `@current_user` and `@primary_user` assigns are available. For LiveView pages, these assigns come from `AshMultiAccount.Phoenix.LiveHook`. For controller pages, add the `AshMultiAccount.Phoenix.LoadMultiAccount` plug to your pipeline: ```elixir pipeline :browser do # ... existing plugs ... plug AshMultiAccount.Phoenix.Plug plug AshMultiAccount.Phoenix.LoadMultiAccount, user_resource: MyApp.Accounts.User end ``` Then use the component in your controller template exactly as you would in a LiveView: ```heex <:account :let={account}> <:add_account :let={url}> <.link href={url}>Add another account ``` ## Single-Account Mode When `@primary_user` is `nil` (no multi-account session), the component renders: - One `:account` entry for just the current user (with `current?: true`, `primary?: true`) - The `:add_account` slot with a link to start the linking flow This means the same component works seamlessly in both single and multi-account modes.