Skip to content

Latest commit

 

History

History
60 lines (43 loc) · 2.16 KB

File metadata and controls

60 lines (43 loc) · 2.16 KB

Core Web — Agent Instructions

SvelteKit 2 + Svelte 5 frontend. See root CLAUDE.md for full context.

Quick Reference

pnpm check              # must pass (svelte-check + TypeScript)
pnpm lint               # prettier + eslint --fix
pnpm build              # production build
pnpm dev                # dev server

Adding a New Page

  1. Create src/routes/<path>/+page.svelte
  2. Use $props(), $state, $derived, $effect — never Svelte 4 syntax
  3. Fetch data in onMount, not SvelteKit load functions
  4. Add onPullRefresh(() => loadData()) for mobile pull-to-refresh
  5. Auth guard: $effect(() => { if (!auth.isLoading && !auth.isAuthenticated) goto('/'); })

Adding a New Component

  1. Place in src/lib/components/common/ (shared) or feature-specific directory
  2. Export from barrel index.ts
  3. Use $props() with TypeScript interface
  4. Use {@render children()} not <slot />

Adding an API Endpoint Call

In src/lib/api.ts, add typed method:

async getFoo(id: string) {
    return this.request<Foo>('GET', `/api/foos/${id}`);
}

shadcn-svelte Components

Available: alert, alert-dialog, avatar, badge, breadcrumb, button, card, dialog, dropdown-menu, empty, input, input-group, label, separator, sheet, skeleton, sonner, spinner, switch, tabs, textarea, tooltip.

NO Popover. Use dropdown-menu or sheet.

Import pattern:

import * as Card from '$lib/components/ui/card'; <!-- namespace -->
import {Button} from '$lib/components/ui/button'; <!-- direct -->

Common Mistakes to Avoid

  1. value={x} vs bind:value={x}: shadcn components use $bindable — use bind: for two-way
  2. $effect not tracking: reading $derived inside falsy if = not tracked. Read before guards.
  3. Plain let in effects: use $state if effects depend on the variable
  4. transform parent + fixed child: CSS transforms create new containing block, breaking fixed positioning
  5. Missing cursor-pointer: add to all interactive/clickable elements
  6. iOS zoom on inputs: use text-base (16px+) on input/textarea elements
  7. Svelte 4 syntax: no <slot />, no export let, no $: reactive declarations