Skip to main content
This guide takes you from a fresh Symfony application to a fully rendered dashboard menu. By the end you’ll have a menu visible in Twig and queryable via the JSON API.
If you use Symfony Flex, steps 1 and 2 (install + bundle registration) are handled automatically by the Flex recipe.
1

Install the bundle

composer require nowo-tech/dashboard-menu-bundle
With Symfony Flex, the recipe registers the bundle in config/bundles.php and creates a default config/packages/nowo_dashboard_menu.yaml. Skip to step 3 if Flex handled this.
2

Configure the bundle

Create or update config/packages/nowo_dashboard_menu.yaml with a minimal configuration:
config/packages/nowo_dashboard_menu.yaml
nowo_dashboard_menu:
    doctrine:
        connection: default
        table_prefix: ''
    cache:
        ttl: 60
        pool: cache.app
    locales: ['en']
    api:
        enabled: true
        path_prefix: /api/menu
    dashboard:
        enabled: true
Import the routes in config/routes.yaml:
config/routes.yaml
nowo_dashboard_menu:
    resource: '@NowoDashboardMenuBundle/Resources/config/routes.yaml'

_nowo_dashboard_menu_dashboard:
    resource: routes_nowo_dashboard_menu.yaml
3

Create the database schema

Generate and run the migration to create the dashboard_menu and dashboard_menu_item tables:
php bin/console nowo_dashboard_menu:generate-migration
php bin/console doctrine:migrations:migrate
If you use a non-default Doctrine connection, run migrations with --conn=YOUR_CONNECTION.
4

Create your first menu

Open the admin dashboard at http://your-app/admin/menus and click New menu.Fill in:
  • Code: sidebar (used to reference this menu in code)
  • Name: Sidebar (display name)
Save the menu, then add items using the item form. Each item needs a label and either a route name or a URL.
Use type: Section for group headers (non-clickable labels) and type: Link for clickable items.
5

Render the menu in Twig

In any Twig template, use the bundle’s Twig functions to load and render the menu:
templates/base.html.twig
{# Load the menu tree and config #}
{% set tree = dashboard_menu_tree('sidebar') %}
{% set config = dashboard_menu_config('sidebar') %}

{# Render using the bundle template #}
{% include '@NowoDashboardMenuBundle/menu.html.twig' with {
    menuTree: tree,
    menuCode: 'sidebar',
    menuConfig: config
} %}
You can also omit config — the template resolves it automatically:
{% set tree = dashboard_menu_tree('sidebar') %}
{% include '@NowoDashboardMenuBundle/menu.html.twig' with {
    menuTree: tree,
    menuCode: 'sidebar'
} %}
6

Query the menu via JSON API

The bundle exposes a JSON API endpoint for SPA frameworks (React, Vue, etc.):
GET /api/menu/sidebar
Example response:
[
  {
    "label": "Dashboard",
    "href": "/dashboard",
    "routeName": "app_dashboard",
    "icon": null,
    "itemType": "link",
    "children": []
  },
  {
    "label": "Settings",
    "href": "/settings",
    "routeName": "app_settings",
    "icon": "bootstrap-icons:gear",
    "itemType": "link",
    "children": [
      {
        "label": "Profile",
        "href": "/settings/profile",
        "routeName": "app_settings_profile",
        "icon": null,
        "itemType": "link",
        "children": []
      }
    ]
  }
]
Override the locale with ?_locale=es. Pass context sets with ?_context_sets=[{"partnerId":1},{}].

What’s next

Core concepts

Learn about the Menu and MenuItem entities, tree structure, and context resolution.

Configuration

Configure cache, locales, icons, permission checkers, and the dashboard.

Context sets

Serve different menus per partner, operator, or tenant using context resolution.

Permissions

Filter menu items per user with a custom permission checker.