agencetwogether/hookshelper
Filament plugin that reveals every render hook available on the current page with a toggle button. Install via Composer, publish the config, and customize the render hook, Heroicon, and minify toggle.
1. Install (dev dependency is fine, but it's a normal package — Filament devs typically just require it):
composer require agencetwogether/hookshelper
2. Publish the config so you can control placement/icon without editing vendor files:
php artisan vendor:publish --tag="hookshelper-config"
Published config (config/hookshelper.php):
return [
'render_hook' => 'global-search.before', // 'panels::' prefix is added for you
'icon' => 'heroicon-m-cursor-arrow-rays',
'tiny_toggle' => false,
];
3. Register the plugin on the panel you actually work in:
use Agencetwogether\HooksHelper\HooksHelperPlugin;
public function panel(Panel $panel): Panel
{
return $panel
->plugins([
HooksHelperPlugin::make(),
]);
}
4. Where to look first
global-search.before is the default render hook).PanelsRenderHook::PAGE_HEADER_ACTIONS_BEFORE (or a custom renderHook(...) call) to a page, and nothing appeared. Toggle hooks on and you immediately see which hooks are actually present on that page and where they sit, so you know whether your hook name is wrong, the page doesn't render that hook, or your component is the problem.5. Sanity check before you rely on it
Confirm the Filament major version you run is supported (the changelog shows Filament v4 support in v0.0.2 and v5 support in v0.0.4). Check composer show filament/filament and pin a compatible release.
Local-only registration (the pattern you should default to)
This is a debugging aid. Gate it so it can never ship to a client-facing admin panel:
->plugins([
...(app()->isLocal() ? [HooksHelperPlugin::make()] : []),
])
Or, cleaner, keep it in a dedicated local panel provider / Panel::make()->id('devtools') so production panels never even boot the plugin.
Tiny toggle during day-to-day work
The full button can crowd the topbar on narrow screens. Set 'tiny_toggle' => true in config and rely on the icon + tooltip; flip it back to false when pairing/demoing so the label makes sense to someone else.
Hook-discovery loop for custom render hooks
PanelsRenderHook::... or $this->renderHook('my-panel::content.start', ...)).renderHook calls. If a hook you wrote isn't listed, it isn't being evaluated on that request — usually wrong page type, wrong panel, or a @once/@if guard upstream.Placement tuning per panel
The render_hook key is global config, not a fluent per-panel option. If you want the toggle in a different spot (e.g. body.start, content.start, topbar.end, or wherever your admin topbar actually exists), edit the config and clear config cache. Don't keep re-publishing — edit the published file.
Pair it with grep, don't replace it
Use the toggle to see what rendered; use ripgrep to see why:
rg "renderHook|PanelsRenderHook|render-hook" app/ resources/views/
The toggle answers "is this hook on this page?"; grep answers "what registered it?". Together they turn a 20-minute guess into a 2-minute check.
Onboarding and code review
New Filament devs don't have the hook map in their head. Have them install it locally and click through the panels they'll own — it's a faster orientation than reading the render hook docs table. Same for reviewing a PR that relocates UI: toggle on, confirm the hook used in the diff is the one actually rendering.
UI iteration without cache clears
Because the toggle is pure UI state, you can iterate on a hook's placement/Blade markup and re-toggle without config:clear/view:clear churn — only publish/view changes need a view cache clear.
render_hook isn't rendered on that page. global-search.before needs a topbar with global search. Disable the topbar, remove global search, or land on an auth page and the toggle vanishes. Fall back to a hook that's always present on the layout, or set 'render_hook' => 'panels::body.start' while debugging.panels:: prefix handling. The config docs say the prefix is added automatically if omitted. If you half-remember this and paste a fully-prefixed hook, verify the button still appears — keep the value in the short form (global-search.before) unless you've confirmed otherwise on your Filament version.php artisan config:cache / config:clear, plus php artisan view:clear if you published and edited the views. A stale config is the #1 reason "the icon change didn't work".hookshelper-views and hookshelper-translations output lives in your repo now; upgrades won't merge changes into them. Only publish if you genuinely need to customise, otherwise you take on drift for free.composer update across Filament majors is where breakage will show up, not in the plugin's own code.tiny_toggle and a panel that non-engineers don't use.render_hook before shipping a fix.render_hook, icon, tiny_toggle, published views, published translations. If you need logging of hook inventory, export to a debug endpoint, or programmatic toggling, this package won't get you there — build around it rather than forking it.->plugins() for this panel? (2) is the resolved config value the hook you think it is (php artisan tinker --execute="dump(config('hookshelper'));")? (3) did you cache config? (4) does that hook exist on this page at all?How can I help you explore Laravel packages today?