EX

extending-shopper

This provides instructions for overriding core components, registering sidebar items, and hooking into events for stock, pricing, and media customizations.

Install

mkdir -p .claude/skills/extending-shopper && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/3848" && unzip -o skill.zip -d .claude/skills/extending-shopper && rm skill.zip

Installs to .claude/skills/extending-shopper

Activation

This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.

Patterns for customizing Shopper in your Laravel application. Sidebar navigation, component overrides, event listeners, and domain features like stock, pricing, and media. Use when extending Shopper behavior in a project.
221 chars✓ has a “when” trigger
Intermediate

Key capabilities

  • Register custom sidebar items
  • Override core components
  • Hook into event listeners
  • Manage stock, pricing, and media domains
  • Inject UI via render hooks
  • Build reusable addons

How it works

Developers register custom sidebar classes or component overrides within the Laravel ServiceProvider to extend Shopper's core functionality without modifying vendor files.

Inputs & outputs

You give it
Custom sidebar class or component override
You get back
Extended admin panel functionality

When to use extending-shopper

  • Add custom items to Shopper sidebar
  • Override Shopper components
  • Implement event listeners for stock updates
  • Customize pricing logic

About this skill

Extending Shopper

Sidebar Navigation

Add Item to Existing Group

// app/Sidebar/ShippingSidebar.php
namespace App\Sidebar;

use Shopper\Sidebar\AbstractAdminSidebar;
use Shopper\Sidebar\Contracts\Builder\Group;
use Shopper\Sidebar\Contracts\Builder\Item;
use Shopper\Sidebar\Contracts\Builder\Menu;

class ShippingSidebar extends AbstractAdminSidebar
{
    public function extendWith(Menu $menu): Menu
    {
        $menu->group(__('shopper::layout.sidebar.catalog'), function (Group $group): void {
            $group->weight(2); // Same weight as CatalogSidebar to merge

            $group->item(__('Shipping'), function (Item $item): void {
                $item->weight(5);
                $item->useSpa();
                $item->route('shopper.shipping.index');
                $item->setIcon('untitledui-truck-01');
                $item->setAuthorized($this->user->hasPermissionTo('browse_shipping'));
            });
        });

        return $menu;
    }
}

Register in AppServiceProvider:

use Shopper\Sidebar\SidebarBuilder;

public function boot(): void
{
    $this->app['events']->listen(SidebarBuilder::class, ShippingSidebar::class);
}

Create New Sidebar Group

$menu->group(__('Logistics'), function (Group $group): void {
    $group->weight(5); // After CustomerSidebar (weight 4)
    $group->setAuthorized();

    $group->item(__('Shipping'), function (Item $item): void {
        $item->weight(1);
        $item->useSpa();
        $item->route('shopper.shipping.index');
        $item->setIcon('untitledui-truck-01');
    });
});

Default Sidebar Groups

GroupWeightClass
Dashboard1DashboardSidebar
Catalog2CatalogSidebar
Sales3SalesSidebar
Customers4CustomerSidebar

Item Options

  • $item->weight(int) - Position (lower = higher)
  • $item->useSpa() - Enable wire:navigate
  • $item->route('name') - Set route
  • $item->setIcon('untitledui-*') - Icon
  • $item->setAuthorized(bool) - Visibility condition

Override Components

Config files in config/shopper/components/:

// config/shopper/components/product.php
return [
    'pages' => [
        'product-index' => App\Livewire\Shopper\Products\Index::class,
        'product-edit' => \Shopper\Livewire\Pages\Product\Edit::class,
    ],
    'components' => [
        'products.form.edit' => App\Livewire\Shopper\Products\EditForm::class,
    ],
];

Extend the base component:

namespace App\Livewire\Shopper\Products;

use Shopper\Livewire\Pages\Product\Index as BaseIndex;

class Index extends BaseIndex
{
    public function table(Table $table): Table
    {
        return parent::table($table)
            ->columns([
                ...parent::table($table)->getColumns(),
                TextColumn::make('custom_field'),
            ]);
    }
}

Events

Listen to Shopper events:

// EventServiceProvider
protected $listen = [
    \Shopper\Core\Events\Products\ProductCreated::class => [YourListener::class],
    \Shopper\Core\Events\Products\ProductUpdated::class => [],
    \Shopper\Core\Events\Products\ProductDeleted::class => [],
    \Shopper\Core\Events\Orders\OrderCreated::class => [SendOrderConfirmation::class],
    \Shopper\Core\Events\Orders\OrderCompleted::class => [],
    \Shopper\Core\Events\Orders\OrderPaid::class => [],
    \Shopper\Core\Events\Orders\OrderCancelled::class => [],
];

Stock Management

use Shopper\Core\Models\Inventory;

$product = Product::query()->find($id);
$inventory = Inventory::query()->where('is_default', true)->first();

$product->setStock(100, $inventory->id);
$product->decreaseStock($inventory->id, 5);
$currentStock = $product->getStock();

Pricing

Amounts stored in cents, supports multi-currency:

use Shopper\Core\Models\Currency;

$product->prices()->create([
    'currency_id' => Currency::where('code', 'USD')->first()->id,
    'amount' => 2999,         // $29.99
    'compare_amount' => 3999, // $39.99 (crossed-out)
    'cost_amount' => 1500,    // $15.00 (cost)
]);

Media Management

// Add thumbnail
$product->addMedia($file)
    ->toMediaCollection(config('shopper.media.storage.thumbnail_collection'));

// Add gallery images
$product->addMedia($file)
    ->toMediaCollection(config('shopper.media.storage.collection_name'));

// Get URL
$thumbnail = $product->getFirstMediaUrl(config('shopper.media.storage.thumbnail_collection'));

Feature Flags

if (\Shopper\Feature::enabled('review')) {
    // Show reviews
}

Configure in config/shopper/features.php.

Helper Functions

FunctionPurpose
shopper_table('products')Prefixed table name (sh_products)
shopper_setting('shop_name')Get shop setting
shopper_fallback_url()Fallback image URL
generate_number()Order number with prefix
shopper()->auth()->user()Authenticated admin

Render Hooks

Shopper provides 30+ UI injection points to extend admin pages without modifying core views. Register hooks in your ServiceProvider:

use Shopper\Facades\Shopper;
use Shopper\View\ProductRenderHook;

public function boot(): void
{
    Shopper::renderHook(ProductRenderHook::EDIT_CONTENT_AFTER, fn () => view('custom.product-extra'));
}

Available hook classes: LayoutRenderHook, ProductRenderHook, OrderRenderHook, CustomerRenderHook, CatalogRenderHook, CollectionRenderHook, SalesRenderHook. See documentation for all hook constants.

Addon System

Build reusable plugins with BaseAddon. Register routes, components, sidebar items, permissions, and assets:

use Shopper\Addon\BaseAddon;
use Shopper\ShopperPanel;

class LoyaltyAddon extends BaseAddon
{
    public function getId(): string
    {
        return 'loyalty';
    }

    public function register(ShopperPanel $panel): void
    {
        $panel->addRoutes(fn () => $this->loadRoutesFrom(__DIR__ . '/../routes/web.php'));
        $panel->addSidebar(LoyaltySidebar::class);
        $panel->addPermissions(['browse_loyalty', 'manage_loyalty']);
    }
}

See documentation at https://docs.laravelshopper.dev for the complete addon lifecycle and AddonManager API.

Custom Routes

// config/shopper/routes.php
return [
    'custom_file' => base_path('routes/shopper.php'),
];

// routes/shopper.php
use App\Livewire\Shopper\Shipping;

Route::get('shipping', Shipping::class)->name('shopper.shipping.index');

When not to use it

  • Modifying core views directly
  • Ignoring existing event listener patterns

Prerequisites

Laravel frameworkShopper package

Limitations

  • Requires adherence to Shopper's specific event and hook classes

How it compares

Unlike modifying core files, this approach uses documented hooks and registration patterns to ensure updates remain compatible with future Shopper releases.

Compared to similar skills

extending-shopper side by side with the closest alternatives in the catalog.

SkillInstallsUpdatedSafetyDifficulty
extending-shopper (this skill)14moNo flagsIntermediate
pennant-development24moNo flagsIntermediate
controller16moNo flagsBeginner
filament-5-resources03moNo flagsIntermediate

Try saying

Example prompts that trigger this skill in your AI assistant.

Search skills

Search the agent skills registry