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

Navigation Laravel Package

kodicomponents/navigation

KodiComponents Navigation is a Laravel package for defining and rendering site navigation menus in code. It helps organize links, nested items, active states, and Blade output, making menus consistent and easier to maintain across an application.

Deep Wiki
Context7

Getting Started

Because the repository is unavailable and there is no public documentation, treat the installed source as the spec. Start there, not with blog posts.

  1. Confirm it installs. composer require kodicomponents/navigation and check Packagist first — with an unknown repo you cannot assume the vendor is still reachable. If it is not on Packagist, add a repositories VCS entry pointing at the fork you control, and pin a commit.
  2. Find the wiring. Open vendor/kodicomponents/navigation/composer.json and look for extra.laravel.providers / aliases. If present, discovery handles registration; if not, add the provider and facade manually in config/app.php. Then read the service provider — it tells you whether the nav is a singleton, what it binds, and whether a Blade directive or config file is published.
  3. Locate the primary class. Expect something in the shape of Navigation/Nav with fluent add()/item() methods and a render() or toArray(). The shipped tests, if any, are the most reliable API reference — read them before writing application code.
  4. First use case: the main layout menu. Register a named menu once in a service provider boot method, then render it in layouts/app.blade.php. Get a two-item menu (Home, Dashboard) rendering before you add active states or authorization.

Version reality check before you invest: last release was September 2020, which predates Laravel 9. Test composer require against your actual framework version early — a ^7.0|^8.0 constraint will block install on 10/11 and you will need --ignore-platform-reqs or a fork with widened constraints.

Implementation Patterns

Register menus centrally, render locally. Define the menu graph in a dedicated NavigationServiceProvider (not AppServiceProvider, which gets crowded) and keep views dumb. This gives you one place to audit links and one place to change when routes move.

// app/Providers/NavigationServiceProvider.php
public function boot(): void
{
    Nav::make('main', function ($nav) {
        $nav->add('Home', route('home'));
        $nav->add('Dashboard', route('dashboard'))->visible(fn () => auth()->check());
        $nav->add('Admin', route('admin.index'))->visible(fn () => Gate::allows('admin'));
    });
}

Resolve labels at render time, not registration time. Call __('nav.home') inside the render/closure path rather than passing a translated string to add(). If you translate at registration and the user switches locale mid-session, the menu stays in the old language.

Active state. Most packages of this vintage infer "active" by comparing the item URL to request()->url(), which breaks on parameterised routes. Prefer an explicit route-name API if one exists (->route('users.*') or ->activeWhen('users.*')); otherwise set active flags yourself in a view composer using request()->routeIs().

Multiple menus, one builder. Use named menus (main, sidebar, footer) rather than one global mutable instance — a singleton menu that every provider appends to becomes order-dependent and impossible to test in isolation.

Authorization. Gate the additions rather than the rendering: an item that never enters the menu cannot leak through a forgotten @can in a template. Combine with visible() closures where the package supports them, but keep a Blade-level guard as the backstop.

Composition with view composers. If items depend on per-request data (current team, unread count), build in a view composer bound to the layout rather than in a global provider, so the menu is built after the request context is known.

Gotchas and Tips

  • Abandonment is the headline risk. Twelve stars, no known repo, and a 2020 release date mean no security patches and no Laravel 10/11 compatibility work. Treat it as vendored code: fork it into your own namespace, or wrap it behind a small internal Menu interface so you can swap in spatie/laravel-navigation or a plain view composer without touching templates.
  • Escaping. A navigation package that emits anchors will usually mark labels as raw. Never pass user-controlled strings (page titles, category names) into a label without escaping — {!! !!} around a cached menu is a stored-XSS vector.
  • Closures do not serialise. If you cache the built menu (Cache::remember), any visible/href closure will fail or silently evaluate once and freeze. Cache only the resolved array form, or cache the underlying data and rebuild the nav each request.
  • Build-before-render ordering. Items added after the layout calls render() simply will not appear. This bites hardest when a controller adds a breadcrumb-style item after the view has begun composing. Establish "menus are complete before the layout renders" as a rule and enforce it in a test.
  • Active-state false positives. Prefix matching catches /admin when you are on /admin/users, and exact matching misses it. Write one feature test per menu item asserting active/inactive on two routes; this is the single highest-value test for any nav package.
  • Discovery off in some environments. If config/app.php has a static provider list or you run with discovery disabled, the facade alias will be missing and you will get a "class not found" that looks like an install failure. Register manually and move on.
  • Debugging. dd(Nav::make('main')->toArray()) before touching Blade. If the menu looks empty in the browser but populated in tinker, the problem is render order or a cached compiled view, not the package.
  • Extension points. Look for Macroable on the nav class first — a macro is a cleaner extension than subclassing. Failing that, bind your own subclass in the container over the package's binding, and keep that override in one provider so upgrades are a one-line diff.
  • Query cost. If items are DB-driven (categories, pages), a naive implementation issues a query per item. Count queries on a page with the menu rendered; eager-load or cache when the number is non-constant.
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.
ably/pubsub-server
mstfkhazaal/defender
mfonte/base62x
karnoweb/metapilot
tobya/bcsapiwrapper
swalker2/cpanel
vish4395/laravel-translation-manager
morningtrain/economic
teksite/systeminfo-laravel
atomcms/voting
run6/weather
siokas/laravelembeddirectives
adamlien/pkuuids
gilsonsouza/lara-doc-generator
manelgavalda/enrollment_mobile
unabomber/timezone
delatbabel/contacts
astritzeqiri/g-recaptcha
kevinongko/laravel-genode
developeruz/laravel-analytics