# Sidebar Disappears / Full Page Reload on Navigation

## Symptom

Clicking a button or link inside a page (Edit, Save, Cancel, breadcrumb, custom action) causes the sidebar to disappear and flash back in. The entire page reloads instead of navigating smoothly.

---

## Root Cause

Filament is built on Livewire 3 which supports **SPA-style navigation** via `wire:navigate`. When a link or redirect uses `wire:navigate`, only the page body is swapped — the sidebar, scripts, and styles stay mounted. Without it, the browser performs a full HTTP navigation and everything reloads.

Filament checks `FilamentView::hasSpaMode()` to decide whether to add `wire:navigate`. If SPA mode is off, every redirect and link causes a full reload.

---

## Fix 1 — Enable SPA Mode for the Whole Panel (Recommended)

Add `->spa()` to the panel definition in `app/Providers/Filament/AdminPanelProvider.php`:

```php
return $panel
    ->default()
    ->id('admin')
    ->spa()   // <-- add this
    ->unsavedChangesAlerts()
    // ...
```

**What this fixes automatically:**
- All Filament-generated links (Edit, View, Create, breadcrumbs, table row clicks)
- All programmatic redirects from `getRedirectUrl()` in `EditRecord`, `CreateRecord`, etc.
- All `Action::make()->url()` buttons rendered by Filament
- Sidebar `NavigationItem` links

This is the **one-line fix** for all reload issues across the entire app. It was applied to this project on 2026-04-21.

**File changed:** `app/Providers/Filament/AdminPanelProvider.php`

---

## Fix 2 — Per-Link Fix (when SPA mode is already on but a specific link still reloads)

If `->spa()` is enabled but a specific custom link still causes a reload, it is likely using a raw `->url()` call that bypasses Filament's SPA awareness. Add `->navigate()` to that specific action or link:

### On a Filament Action button:
```php
Action::make('edit')
    ->url(fn () => SomeResource::getUrl('edit', ['record' => $this->record]))
    ->navigate()   // <-- tells Filament to add wire:navigate
```

### On a NavigationItem:
```php
NavigationItem::make('purchase-orders')
    ->url(fn () => ListOrders::getUrl())
    ->navigate()   // <-- add this if the link still reloads
```

### On a raw HTML link in a blade view:
```html
<!-- Without navigate — causes full reload -->
<a href="{{ $url }}">Click</a>

<!-- With navigate — SPA navigation -->
<a href="{{ $url }}" wire:navigate>Click</a>
```

> **✅ Confirmed fix (2026-04-21):** The custom `record-navigation-tabs.blade.php` widget renders the View / Edit / Vendor Bills / Receipts tab bar as plain `<a href>` tags. These bypass Filament's link generation entirely so `->spa()` on the panel has no effect on them. The fix is to add `wire:navigate` directly to every `<a>` tag in that blade file. There are two loops in the file (one inside the product identity card, one for the standalone tab bar) — both need it.
>
> **File fixed:** `plugins/webkul/support/resources/views/filament/widgets/record-navigation-tabs.blade.php`
>
> ```html
> <a href="{{ $item['url'] }}" wire:navigate @class([...])>
> ```

---

## Fix 3 — Programmatic Redirect from a Page Class

If a page class (e.g. a custom `EditRecord`) does its own redirect and bypasses `getRedirectUrl()`, call `redirect()` with `navigate: true`:

```php
// Full page reload
$this->redirect($url);

// SPA navigation
$this->redirect($url, navigate: true);
```

Filament's built-in `EditRecord` and `CreateRecord` already do:
```php
$this->redirect($redirectUrl, navigate: FilamentView::hasSpaMode($redirectUrl));
```
So enabling `->spa()` panel-wide (Fix 1) covers these automatically.

---

## Summary

| Situation | Fix |
|-----------|-----|
| Everything in the app reloads | Add `->spa()` to `AdminPanelProvider` |
| One specific Action button reloads | Add `->navigate()` to that Action |
| One specific NavigationItem reloads | Add `->navigate()` to that NavigationItem |
| Raw blade `<a href>` reloads | Add `wire:navigate` attribute |
| View/Edit/tab bar in record-navigation-tabs reloads | Add `wire:navigate` to both `<a>` loops in `record-navigation-tabs.blade.php` |
| Custom `$this->redirect()` in a page | Pass `navigate: true` |

---

## Reference

- **Panel SPA config:** `app/Providers/Filament/AdminPanelProvider.php`
- **Livewire navigate docs:** https://livewire.laravel.com/docs/navigate
- Filament checks `FilamentView::hasSpaMode($url)` before every redirect — enabling `->spa()` makes this return `true` globally.
