Menu editor API
This is the per-item reference for Avo's menu DSL. For task-oriented guides and worked examples, see the Menu editor guide.
All menus are configured in config/initializers/avo.rb by assigning a Proc that uses the DSL below:
Avo.configure do |config|
config.main_menu = -> {
section "Content", icon: "tabler/outline/files" do
resource :posts
end
}
endThree menus are configurable:
| Config key | Renders in | Item types rendered |
|---|---|---|
main_menu | The sidebar | All item types |
profile_menu | The profile widget in the sidebar footer | link_to only |
header_menu | The top navigation bar | link_to only |
Structure items
-> section
Top-level container, rendered with a prominent header made of a name and an icon. Sections group related groups and items at the highest level of the menu.
section "Resources", icon: "heroicons/outline/academic-cap" do
group "Academia" do
resource :course
end
all_tools
end- Options:
icon,collapsable,collapsed,visible - Default
name:nil— the name may be omitted for an unlabeled section
-> group
Sub-category nested inside a section, rendered as a collapsable label that clusters related items. Groups can also sit at the top level, but the recommended hierarchy is section → group → item.
group "Blog", collapsable: true, collapsed: true do
resource :posts
resource :comments
end- Options:
collapsable,collapsed,visible - Not supported:
icon
A group automatically hides itself when every item inside it is invisible (for example, when all of them fail their visible checks).
Item types
-> link_to
Generates a link to any path. link is an alias — the two are interchangeable.
link_to "Google", path: "https://google.com", target: :_blank| Option | Description |
|---|---|
path | The URL the link points to. May be passed positionally: link_to "Home", main_app.root_path. |
target | Standard anchor target. :_blank also renders a small external-link icon. |
active | Highlight matching mode — see below. |
title | Native title attribute (hover tooltip). Rendered in the header and profile menus. Tooltips are opt-in; without title, none is shown. |
method | Non-GET HTTP method, submitted through Turbo. Honored in the profile and header menus. |
params | Extra query parameters appended to the path. Honored in the profile and header menus. |
Also accepts the shared icon, hotkey, data, and visible options.
active controls when the link is highlighted as active:
| Value | Behavior |
|---|---|
:inclusive (default) | Active when the current path starts with the link's path — useful for nested routes. |
:exclusive | Active only on an exact path match. |
true / false | Forces the state. |
active is ignored on sub-items
For links nested inside a resource block, Avo computes the active sub-item itself — inclusively, favoring the most specific (longest) matching path — and a per-link active: has no effect.
-> resource
Generates a link to a resource's Index view. Pass a symbol (:users) or the full class name as a String ("Avo::Resources::User"). Items whose resource can't be found are silently skipped.
resource :posts
resource :posts, label: "News posts"
resource :posts, params: { status: "published" }| Option | Description |
|---|---|
label | Overrides the resource's navigation label. |
params | Hash of query params appended to the link, or a Proc returning one (evaluated with access to resource). |
Also accepts the shared icon, hotkey, data, and visible options. When no hotkey is given, the resource class's own self.hotkey is used as a fallback. When no icon is given, the resource class's self.icon is used.
Passing a block nests sub-items under the resource — see the sub-items guide. Any item type can be nested; nested items don't render icons, and a nested action inherits the enclosing resource.
resource :projects do
link_to "First project", path: "/admin/resources/projects/1"
resource :tasks
dashboard :sales
action Avo::Actions::ExportData # inherits :projects
endFor readability you can wrap nested items in a subitems do ... end block — it behaves identically to listing them directly.
-> dashboard
Generates a link to a dashboard. Pass the dashboard's id or name.
dashboard :dashy
dashboard "Sales", label: "Sales dashboard"-> page
Generates a link to one of your pages. Pass the page's class name as a String.
page "Avo::Pages::Settings"
page "Avo::Pages::Settings", label: "App configuration"- Options:
label(defaults to the page'snavigation_label, falling back to itstitle), plus the sharedicon,hotkey,data, andvisibleoptions - Availability: provided by the
avo-formsadd-on
Use the String form
Reference the page by its class name in quotes, not the bare constant. The String is resolved when the menu renders, so the page class isn't autoloaded while your initializer is parsed — which is what prevents boot and reload errors. The bare constant still works, but the String form is recommended.
-> form
Generates a link to one of your forms. Pass the form's class name as a String (recommended, for the same autoloading reasons as page) or the class itself.
form "Avo::Forms::AppSettings"
form "Avo::Forms::AppSettings", label: "Settings"-> board
Generates a link to one of your kanban boards. Pass the board's id.
board 1- Options: the shared
icon,hotkey,data, andvisibleoptions; the label is the board's name - Availability: provided by the
avo-kanbanadd-on
-> action
Adds an item that triggers one of your actions. Clicking it opens the action's modal, just like the per-resource Actions dropdown. Pass the action class or its name as a String.
action Avo::Actions::ExportData, resource: :projects| Option | Description |
|---|---|
resource | The resource whose URL the action runs under. Required at the top level; inherited from the enclosing resource block when nested (an explicit resource: still overrides it). Omitting it at the top level silently skips the item. |
label | Overrides the action's self.name. |
Also accepts the shared icon, hotkey, data, and visible options.
- Validation: only standalone actions (
self.standalone = true) can be added — the menu has no selected records. Non-standalone actions are skipped with a log warning.
-> render
Renders a renderable object — a partial or a View Component. Partials accept locals, following the same pattern as Rails' render.
render "avo/sidebar/items/custom_tool"
render "avo/sidebar/items/custom_tool", locals: { something: :here }
render Super::Dooper::Component.new(something: :here)Bulk helpers
-> all_resources
Adds every resource available for navigation, except those explicitly excluded.
group "Resources" do
all_resources except: [:users, :orders]
endexcept: Array of route keys (the plural symbol, e.g.:usersforAvo::Resources::User) to leave out
WARNING
all_resources respects your authorization rules, so make sure def index? is enabled in the resource's policy.
-> all_dashboards
Adds every dashboard available for navigation, except those explicitly excluded.
group "Dashboards" do
all_dashboards except: [:sales, :analytics]
endexcept: Array of dashboardids to leave out
-> all_pages
Adds every main page — sub-pages are reached through their parent page's own navigation.
section "Configuration", icon: "tabler/outline/settings" do
all_pages
end- Availability: provided by the
avo-formsadd-on
-> all_forms
Adds every form defined under the Avo::Forms namespace.
section "Forms", icon: "tabler/outline/forms" do
all_forms
end- Availability: provided by the
avo-formsadd-on
-> all_boards
Adds every kanban board.
section "Boards", icon: "tabler/outline/layout-kanban" do
all_boards
end- Availability: provided by the
avo-kanbanadd-on
-> all_tools
Adds every custom tool by rendering each tool's partial.
group "All tools" do
all_tools
endShared options
These options are accepted by every menu item.
-> visible
Controls whether the item renders.
resource :users, visible: -> { current_user.admin? }- Type: Boolean or Proc
- Default:
true
Inside the Proc you have access to:
current_user— as configured by the current user methodcontextparams— the current request's paramsview_context— which also gives you route helpers, e.g.view_context.main_app.posts_path
-> icon
An icon rendered next to the item's label. Use a full path like "tabler/outline/building-store" or "heroicons/outline/user-group"; bare names like "globe" are looked up in the bundled icon sets.
resource :reviews, icon: "heroicons/outline/star"- Type: String
- Default:
nil - Supported on:
sectionand individual items (link_to,resource,dashboard,page,form,board,action) - Not supported on:
groupand sub-items nested inside aresourceblock
Icons come from Tabler Icons (preferred in Avo 4) or Heroicons (outline and solid variants).
-> hotkey
A keyboard shortcut that jumps to the item from anywhere in the admin panel, rendered as a <kbd> badge next to the label.
resource :post, hotkey: "g p"- Type: String, in @github/hotkey syntax — space-separated keys are sequences (
"g p"= press g then p) - Default:
nil; forresourceitems, falls back to the resource class'sself.hotkey
-> data
Arbitrary data attributes added to the item's HTML element — for example data: { turbo: false } to make a link perform a regular request, or data: { turbo_method: :delete } to send a non-GET request.
resource :users, data: { turbo: false }- Type: Hash
- Default:
{}
-> collapsable
Makes a section or group collapsible, adding an arrow icon to its header. The collapsed/expanded state is stored in the browser's Local Storage and remembered across page loads.
section "Resources", icon: "heroicons/outline/academic-cap", collapsable: true do
# ...
end- Type: Boolean
- Default:
false - Supported on:
section,group
-> collapsed
Collapses the section or group by default. Only takes effect on a user's first visit — once they have a stored preference, that preference wins.
group "Blog", collapsable: true, collapsed: true do
# ...
end- Type: Boolean
- Default:
false - Supported on:
section,group