Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Nova Treeview Laravel Package

reedware/nova-treeview

A Laravel Nova package that displays resources in a hierarchical tree view, making it easy to organize, navigate, and manage parent-child relationships and nested records directly within your Nova admin panel.

View on GitHub
Deep Wiki
Context7

Getting Started

This is a small, single-purpose Nova extension: it swaps Nova's flat sidebar menu for a collapsible tree. Treat it as a UI patch, not a framework — the whole integration surface is a config file, an asset registration, and one Vue component.

Install and orient yourself

composer require reedware/nova-treeview
php artisan vendor:publish --provider="Reedware\NovaTreeview\TreeviewServiceProvider"

Before writing any code, read these four things in the vendor directory, in this order:

  1. composer.json — the Nova and Laravel version constraints. This single file tells you whether the package can work on your install at all.
  2. src/*ServiceProvider.php — where assets get registered (Nova::script/Nova::style vs. a compiled public/ bundle) and whether a config merge happens.
  3. config/nova-treeview.php (if published) — the menu/tree structure shape.
  4. resources/js/ — the Vue component, so you can see which Nova globals it depends on (Nova.app, Nova.booting, Nova.config('base'), etc.).

First use case: nested admin navigation

The canonical job is an app whose Nova sidebar has outgrown a flat list — a CMS with Sections → Categories → Pages, or a multi-tenant tool with per-tenant groups. You want indentation, expand/collapse state, and parent rows that are labels rather than links.

Minimal path to a working tree:

// config/nova-treeview.php (shape will vary — match the published file)
return [
    'items' => [
        ['label' => 'Content', 'children' => [
            ['label' => 'Pages',   'resource' => 'pages'],
            ['label' => 'Posts',   'resource' => 'posts'],
        ]],
        ['label' => 'Settings', 'children' => [
            ['label' => 'Users',   'resource' => 'users'],
        ]],
    ],
];

Then verify in the browser, not the terminal. php artisan serve won't tell you anything about whether the sidebar rendered — open Nova, hard-refresh (the sidebar is client-side and aggressively cached by the browser), and check the console for Vue warnings. That console is your primary feedback loop for the entire package.

Expectation setting: last release was September 2020, 4 stars, zero dependents. Assume no upstream fixes and plan to vendor or fork the component if you adopt it. Do a 30-minute spike on a throwaway Nova install before proposing it for a production app.

Implementation Patterns

Config-driven tree as the single source of truth

Put the navigation structure in the config file and keep controllers/resources ignorant of it. This lets you diff the menu in code review and lets non-developers read it. If the package's config only supports a flat list with a parent key, normalize it yourself into a nested array in a small helper rather than hand-maintaining indentation levels.

Filter by authorization at boot, not in the component

The Vue layer usually has no idea who the user is beyond what Nova exposes. Prefer computing the visible tree server-side in a NovaServiceProvider::boot() or a dedicated NavigationTree class:

// app/Providers/NovaServiceProvider.php
public function boot()
{
    parent::boot();

    Nova::script('nova-treeview-auth', __DIR__.'/../../public/js/tree-auth.js');

    config(['nova-treeview.items' => app(NavigationTree::class)->forUser(request()->user())]);
}

Guard against the request being null during console commands (request()->user() is null in artisan context) — a common source of "works in browser, explodes in queue worker" bugs.

Blend with, don't fight, Nova's own menu

Nova 3/4 still renders Nova::mainMenu() and any registered tools/cards. Two viable patterns:

  • Replace: hide the native menu via CSS and drive everything from the tree. Cleaner look, but you must reimplement dashboards, lenses, and any third-party tool links manually.
  • Augment: keep Nova's menu and use the treeview only for a specific group. Usually the safer bet for a package this old — you don't lose access to tools you didn't build.

Per-environment trees

Because it's config, you get environment variation for free. Use a different tree in local (show all resources, including experimental ones) vs. production (curated). App::environment() checks inside the config file are legitimate here.

Link generation

If items support a url or resource key, generate URLs with Nova's route helpers (Nova::resourcePath('posts'), route('nova.pages...')) rather than hand-written strings. Hardcoded /nova/resources/posts breaks the moment someone changes the Nova path in config/nova.php.

Persist expand/collapse state

Users hate re-expanding the same branch on every page load. If the component doesn't do it, wrap it: store open node keys in localStorage keyed by user ID, and hydrate on mount. This is the single highest-value addition you'll make to the package.

Gotchas and Tips

Nova version compatibility is the whole ballgame. A 2020 package targets Nova ~3.x and its compiled asset pipeline. Nova 4 rewrote the front end substantially. Check composer.json constraints against your nova version first; if they don't match, the component will likely fail at Nova.booting with an undefined mixin or a missing Nova.config key. Don't assume --ignore-platform-reqs is a fix.

Assets are pre-compiled. Most packages of this vintage ship a built dist/ and never expect you to run npm. If you fork to patch the Vue component, you own the toolchain: you'll need a matching laravel-nova npm dependency, and npm run prod against a mismatched Nova will produce subtly broken CSS. Budget a day for that, not an hour.

Config caching. config:cache in production will freeze your authorization filter into the cached tree if you compute it at config-load time instead of request time. Keep the filtering in a service provider or middleware that runs per-request, not inside the config file, if the tree varies by user.

Browser cache is the #1 false debugging signal. After editing config or assets, hard-refresh. If the sidebar looks stale, check nova-assets/mix-manifest hashes before you start reading source.

Debugging order when the sidebar is blank or duplicated:

  1. Browser console — a Vue error almost always appears here and names the component.
  2. php artisan route:list | grep nova — confirm the Nova path matches what your tree URLs assume.
  3. Inspect the rendered DOM — is the component mounted but empty (data problem) or absent entirely (asset/registration problem)? These have completely different fixes.
  4. Only then read the package source.

Extension points are thin. Expect no events, no published contracts, no interfaces. The practical extension strategy is: publish the config, then either (a) override the config at runtime, or (b) fork the Vue component and register your own script with a distinct name so both load and yours wins. Prefer (a); resort to (b) only for behavior changes.

CSS specificity fights. A sidebar replacement lives next to Nova's own styles and any theme package. Isolate your overrides under a single wrapper class rather than targeting Nova's generated classes, which change between minor versions.

Have an exit plan. With 0 dependents and no releases since 2020, treat the package as a design reference as much as a dependency. The pattern — nested array config + a Vue component rendering it into the sidebar slot — is ~200 lines to reimplement. If the spike shows friction, copying the idea into your own Nova card/tool is often cheaper than maintaining a dead dependency, and it survives the Nova 5 upgrade.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
htinlynn/genius-helper
maco-studios/hephaestus
elmogy/larafast
xeviant/laravel-paystack
gorilladash/laravel-website-sdk
martialbe/flysystem-oss
chondal/3312client
jeroen-g/flickr
opscale-co/nova-genbi
itsjustvita/laravel-retention
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator