AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
SKILL verified MIT Self-run

Frontend Patterns

skill-pekral-cursor-rules-frontend-patterns · by pekral

Use when building Livewire/Blade/Alpine UI in a Laravel app — component composition, state placement, performance, forms, and loading/empty/error states.

No reviews yet
0 installs
32 views
0.0% view→install

Install

$ agentstack add skill-pekral-cursor-rules-frontend-patterns

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/skill-pekral-cursor-rules-frontend-patterns)

Reliability & compatibility

Security review passed
0 installs to date
no reviews yet
2mo ago

Declared compatibility

Claude CodeClaude Desktop

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Frontend Patterns? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Constraints

  • Apply @rules/laravel/livewire.mdc — class in app/Livewire, view in resources/views/livewire, extend Livewire\Component; components are slim entry points; delegate business logic to Actions/Services; inject dependencies via boot(), never as method params; Blade stays presentation-only.
  • Apply @rules/laravel/filament.mdc — prefer Filament form/table components for admin UIs; custom Blade+Tailwind needs a registered theme.
  • Apply @rules/laravel/architecture.mdc — keep query/business logic out of views and components.
  • Apply @rules/sql/optimalize.mdc — eager-load to avoid N+1 in loops rendered by Blade.
  • Stack is Blade + Livewire + Alpine.js + Filament + Tailwind. No React/Vue/Next — never output useState/useEffect/useMemo/JSX/Framer Motion/React Query.

Use when

  • Composing UI from Blade/Livewire components.
  • Deciding where state lives (Livewire vs Alpine).
  • Optimizing render/network cost of a Livewire view.
  • Building forms with validation.
  • Handling loading, empty, error, and offline states.

Component composition

Compose; do not inherit. Prefer small components with slots over big configurable ones.

{{-- resources/views/components/card.blade.php (anonymous component) --}}
@props(['variant' => 'default'])
class(['card', 'card-outlined' => $variant === 'outlined']) }}>
    {{ $slot }}

    Title
    Content
  • Anonymous components (view-only, in resources/views/components) for pure presentation.
  • Class components (app/View/Components) only when the component needs PHP logic to prepare data.
  • {{ $attributes }} forwards caller classes/attributes — merge, don't overwrite.
  • Named slots (``) replace prop-drilling content.

Livewire nesting

A "compound" UI is a parent Livewire component holding child Livewire components. Children are independent; pass data down via props and communicate up via events/listeners — never tight coupling.

@foreach ($rows as $row)
    id" />
@endforeach

Always set :key on nested components and loop items so Livewire tracks identity across re-renders.


State placement: Livewire vs Alpine

Put state where it belongs. The wrong choice causes either chattiness or lost server state.

  • Livewire public properties — server-authoritative data, anything persisted or validated, anything other components react to.
  • Livewire computed properties (#[Computed]) — derived values from properties/DB; cached per request, keeps the view clean.
  • Alpine x-data — purely local UI state that the server never needs: dropdown open/closed, active tab, hover, optimistic toggles.
{{-- local-only: no server round-trip --}}

    Menu
    …
// derived server state
#[Computed]
public function total(): int
{
    return $this->items->sum('price');
}

Rule of thumb: if toggling it should hit the database or affect validation, it is Livewire; if it is ephemeral chrome, it is Alpine. Bridge the two with @entangle only when both sides genuinely need the value.


Performance

  • wire:key in loops — mandatory; without it Livewire mis-reconciles DOM and loses focus/state.
  • Tune wire:model — default is deferred (syncs on action). Use .live only when the server must react to every keystroke; prefer .blur or .debounce.500ms for inputs to cut requests.
  • Lazy / deferred loading — render expensive components after first paint with `, or #[Lazy]` on the class, to keep the initial response fast.
  • Pagination — use WithPagination; never load full tables into a property.
  • Avoid N+1 in views — eager-load relations in the query before passing to Blade; cross-reference @rules/sql/optimalize.mdc. A relation accessed inside a @foreach without eager loading fires one query per row.
$this->orders = Order::with('customer')->latest()->paginate(20);
  • Asset stacks — register component CSS/JS once with @once + @push('scripts') so repeated components don't duplicate output.

Forms

Prefer Livewire form objects to keep components slim and validation reusable.

// app/Livewire/Forms/MarketForm.php
class MarketForm extends Form
{
    #[Validate('required|string|max:200')]
    public string $name = '';

    #[Validate('required|string')]
    public string $description = '';
}
// component
public MarketForm $form;

public function save(CreateMarket $action): void   // Action injected via boot() or method DI
{
    $this->validate();
    $action->handle($this->form->toArray());
    $this->reset('form');
}
  • Real-time validationwire:model.blur plus an updated() hook (or per-field $this->validateOnly($field)) validates as the user leaves each field without validating the whole form on every key.
  • Keep messages()/attributes() free of identity-revealing detail per @rules/security/frontend.md.
  • For admin CRUD, prefer Filament forms over hand-built ones.

Loading, empty, error, offline states

Design all four states, not just the happy path.

{{-- loading --}}

    Save
    Saving…

{{-- empty --}}
@forelse ($orders as $order)
    id" />
@empty
    
@endforelse

{{-- offline --}}
You are offline — changes will retry.
  • Errors — surface failures with session()->flash() + a role="alert" region, or a validation message; never swallow exceptions in the component. Delegate the actual work to an Action that can throw, and catch only to present a safe message.
  • Skeletons — show wire:loading placeholders for lazy/deferred components so layout doesn't jump.

Progressive enhancement with Alpine

Render meaningful HTML server-side first; layer Alpine for interactivity so the page is useful before JS runs and degrades gracefully if it doesn't.

  {{-- works without JS via native ; Alpine enhances --}}
    Filters
    …

Keep Alpine logic small and inline; if it grows beyond a few expressions, move the state into a Livewire component.


Done when

  • Components are composed from slots/attributes; no oversized configurable mega-components.
  • State sits on the correct layer (Livewire for server/validated, Alpine for local chrome).
  • Every loop and nested component has a stable wire:key/:key.
  • wire:model strategy minimizes requests; no .live where .blur/.debounce suffices.
  • Lists eager-load relations — no N+1 in Blade.
  • Forms use form objects + validation; admin CRUD reuses Filament.
  • Loading, empty, error, and offline states are all handled.
  • No React/Vue artifacts; business logic stays in Actions/Services, not the component.

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.