Customization options
Change the app name
On the main navbar next to the logo, Avo generates a link to the homepage of your app. The label for the link is usually computed from your Rails app name. You can customize that however, you want using config.app_name = 'Avocadelicious'.
Since Avo 2.32.6 the app_name option is callable using a block. This is useful if you want to reference a I18n.t method or something more dynamic.
Avo.configure do |config|
config.app_name = -> { I18n.t "app_name" }
endTimezone and Currency
Your data-rich app might have a few fields where you reference date, datetime, and currency fields. You may customize the global timezone and currency with config.timezone = 'UTC' and config.currency = 'USD' config options.
Resource Index view
There are a few customization options to change how resources are displayed in the Index view.
Resources per page
You may customize how many resources you can view per page with config.per_page = 24.

Per page steps
Similarly customize the per-page steps in the per-page picker with config.per_page_steps = [12, 24, 48, 72].

Resources via per page
For has_many associations you can control how many resources are visible in their Index view with config.via_per_page = 8.
Default view type
The ResourceIndex component supports two view types :table and :grid. You can change that by config.default_view_type = :table. Read more on the grid view configuration page.


ID links to resource
On the Index view, each row has the controls component at the end, which allows the user to go to the Show and Edit views and delete that entry. If you have a long row and a not-so-wide display, it might not be easy to scroll to the right-most section to click the Show link.
You can enable the id_links_to_resource config option to make it easier.
Avo.configure do |config|
config.root_path = '/avo'
config.app_name = 'Avocadelicious'
config.id_links_to_resource = true
endThat will render all id fields in the Index view as a link to that resource.

Resource controls on the left side
Watch the demo videoBy default, the resource controls are located on the right side of the record rows, which might be hidden if there are a lot of columns. You might want to move the controls to the left side in that situation using the resource_controls_placement option.
Avo.configure do |config|
config.resource_controls_placement = :left
end
Container width
Avo.configure do |config|
config.full_width_index_view = false
config.full_width_container = false
endAvo's default main content is constrained to a regular Tailwind CSS container. If you have a lot of content or prefer to display it full-width, you have two options.
Display the Index view full-width
Using full_width_index_view: true tells Avo to display the Index view full-width.
Display all views full-width
Using full_width_container: true tells Avo to display all views full-width.
Cache resources on the Index view
Avo caches each resource row (or Grid item for Grid view) for performance reasons. You can disable that cache using the cache_resources_on_index_view configuration option. The cache key is using the record's id and created_at attributes and the resource file md5.
INFO
If you use the visibility option to show/hide fields based on the user's role, you should disable this setting.
Avo.configure do |config|
config.cache_resources_on_index_view = false
endContext
In the Resource and Action classes, you have a global context object to which you can attach a custom payload. For example, you may add the current_user, the current request params, or any other arbitrary data.
You can configure it using the set_context method in your initializer. The block you pass in will be instance evaluated in Avo::ApplicationController, so it will have access to the current_user method or Current object.
Avo.configure do |config|
config.set_context do
{
foo: 'bar',
params: request.params,
}
end
end_current_user
It's recommended you don't store your current user here but using the current_user_method config.
You can access the context data with ::Avo::App.context object.
Eject views
If you want to change one of Avo's built-in views, you can eject it, update it and use it in your admin.
Prepared templates
We prepared a few templates to make it.
bin/rails generate avo:eject :logo will eject the _logo.html.erb partial.
▶ bin/rails generate avo:eject :logo
Running via Spring preloader in process 20947
create app/views/avo/logo/_logo.html.erbA list of prepared templates:
:logo➡️app/views/avo/partials/_logo.html.erb:head➡️app/views/avo/partials/_head.html.erb:header➡️app/views/avo/partials/_header.html.erb:footer➡️app/views/avo/partials/_footer.html.erb:scripts➡️app/views/avo/partials/_scripts.html.erb:sidebar_extra➡️app/views/avo/partials/_sidebar_extra.html.erb
Logo
In the app/views/avo/partials directory, you will find the _logo.html.erb partial, which you may customize however you want. It will be displayed in place of Avo's logo.

Header
The _header.html.erb partial enables you to customize the name and link of your app.

Footer
The _footer.html.erb partial enables you to customize the footer of your admin.

Scripts
The _scripts.html.erb partial enables you to insert scripts in the footer of your admin.
Eject any template
You can eject any partial from Avo using the partial path.
▶ bin/rails generate avo:eject app/views/layouts/avo/application.html.erb
create app/views/layouts/avo/application.html.erbWARNING
Once ejected, the views will not receive updates on new Avo releases. You must maintain them yourself.
Breadcrumbs
By default, Avo ships with breadcrumbs enabled.

You may disable them using the display_breadcrumbs configuration option.
Avo.configure do |config|
config.display_breadcrumbs = false
endThe first item on the breadcrumb is Home with the root_path URL. You can customize that using the set_initial_breadcrumbs block.
Avo.configure do |config|
config.set_initial_breadcrumbs do
add_breadcrumb "Casa", root_path
add_breadcrumb "Something else", something_other_path
end
endAvo uses the breadcrumbs_on_rails gem under the hood.
Breadcrumbs for custom pages
You can add breadcrumbs to custom pages in the controller action.
class Avo::ToolsController < Avo::ApplicationController
def custom_tool
add_breadcrumb "Custom tool"
end
endPage titles
When you want to update the page title for a custom tool or page, you only need to assign a value to the @page_title instance variable in the controller method.
class Avo::ToolsController < Avo::ApplicationController
def custom_tool
@page_title = "Custom tool page title"
end
endAvo uses the meta-tags gem to compile and render the page title.
Home path
When a user clicks your logo inside Avo or goes to the /avo URL, they will be redirected to one of your resources. You might want to change that path to something else, like a custom page. You can do that with the home_path configuration.
Avo.configure do |config|
config.home_path = "/avo/dashboard"
endUse a lambda function for the home_path
Since v2.8.0You can also use a lambda function to define that path.
Avo.configure do |config|
config.home_path = -> { avo.dashboard_path(:dashy) }
endWhen you configure the home_path option, the Get started sidebar item will be hidden in the development environment.
Now, users will be redirected to /avo/dashboard whenever they click the logo. You can use this configuration option alongside the set_initial_breadcrumbs option to create a more cohesive experience.
Avo.configure do |config|
config.home_path = "/avo/dashboard"
config.set_initial_breadcrumbs do
add_breadcrumb "Dashboard", "/avo/dashboard"
end
endMount Avo under a nested path
You may need to mount Avo under a nested path, something like /uk/admin. In order to do that, you need to consider a few things.
- Move the engine mount point below any route for custom tools.
Rails.application.routes.draw do
# other routes
authenticate :user, ->(user) { user.is_admin? } do
scope :uk do
scope :admin do
get "dashboard", to: "avo/tools#dashboard" # custom tool added before engine
end
mount Avo::Engine, at: Avo.configuration.root_path # engine mounted last
end
end
end- The
root_pathconfiguration should only be the last path segment.
# 🚫 Don't add the scope to the root_path
Avo.configure do |config|
config.root_path = "/uk/admin"
end
# ✅ Do this instead
Avo.configure do |config|
config.root_path = "/admin"
end- Use full paths for other configurations.
Avo.configure do |config|
config.home_path = "/uk/admin/dashboard"
config.set_initial_breadcrumbs do
add_breadcrumb "Dashboard", "/uk/admin/dashboard"
end
endCustom view_component path
You may not keep your view components under app/components and want the generated field view_components to be generated in your custom directory. You can change that using the view_component_path configuration key.
Avo.configure do |config|
config.view_component_path = "app/frontend/components"
endCustom query scopes
You may want to change Avo's queries to add sorting or use gems like friendly. You can do that using resolve_query_scope for multiple records and resolve_find_scope when fetching one record.
Custom scope for Index page
Using resolve_query_scope you tell Avo how to fetch the records for the Index view.
class UserResource < Avo::BaseResource
self.resolve_query_scope = ->(model_class:) do
model_class.order(last_name: :asc)
end
endCustom scope for Show and Edit pages
WARNING
The resolve_find_scope method is deprecated in favor of find_record_method (below).
If you're following the friendly_id example, you must also add the friendly_id configuration to the model definition.
class User < ApplicationRecord
extend FriendlyId
friendly_id :name, use: :slugged
endCustom find method for Show and Edit pages
Using find_record_method you tell Avo how to fetch one record for Show and Edit views and other contexts where a record needs to be fetched from the database.
This is very useful when you use something like friendly gem, custom to_param methods on your model, and even the wonderful prefix_id gem.
Custom to_param method
The following example shows how you can update the to_param (to use the post name) method on the User model to use a custom attribute and then update the UserResource so it knows how to search for that model.
class PostResource < Avo::BaseResource
self.find_record_method = ->(model_class:, id:, params:) do
# If the id is an integer use the classic `find` method.
# But if it's not an integer, search for that post by the slug.
id.to_i == 0 ? model_class.find_by_slug(id) : model_class.find(id)
end
endclass Post < ApplicationRecord
before_save :update_slug
def to_param
slug || id
end
def update_slug
self.slug = name.parameterize
end
endUsing the friendly gem
class UserResource < Avo::BaseResource
self.find_record_method = ->(model_class:, id:, params:) do
# We have to add .friendly to the query
model_class.friendly.find! id
end
endclass User < ApplicationRecord
extend FriendlyId
friendly_id :name, use: :slugged
endUsing prefixed_ids gem
You really don't have to do anything on Avo's side for this to work. You only need to add the has_prefix_id the model as per the documentation. Avo will know how to search for the record.
class Course < ApplicationRecord
has_prefix_id :course
endDisable features
You might want to disable some Avo features. You can do that using the disabled_features option.
# config/initializers/avo.rb
Avo.configure do |config|
config.disabled_features = [:global_search]
endAfter this setting, the global search will be hidden for users.
Supported options:
global_search
Customize profile name, photo, and title
You might see on the sidebar footer a small profile widget. The widget displays three types of information about the user; name, photo, and title.
Customize the name of the user
Avo checks to see if the object returned by your current_user_method responds to a name method. If not, it will try the email method and then fall back to Avo user.
Customize the profile photo
Similarly, it will check if that current user responds to avatar and use that as the src of the photo.
Customize the title of the user
Lastly, it will check if it responds to the avo_title method and uses that to display it under the name.
Customize the sign-out link
Please follow this guide in authentication.
Skip show view
In the CRUD interface Avo adds the Show view by default. This means that when your users will see the view icon to go to that detail page and they will be redirected to the Show page when doing certain tasks (update a record, run an action, etc.).
You might not want that behavior and you might not use the Show view at all and prefer to skip that and just use the Edit view. Adding config.resource_default_view = :edit to your avo.rb configuration file will tell Avo to skip it and use the Edit view as the default resource view.
# config/initializers/avo.rb
Avo.configure do |config|
config.resource_default_view = :edit
end
Friendly.rb - Your friendly European Ruby Conference