Files
the-collective-hub/.github/instructions/svelte5.instructions.md
T
KungRaseri b192cd53ba docs(copilot): add Copilot instructions for The Collective Hub
- Add comprehensive project overview and core philosophy
- Document file structure reference for the codebase
- Create key files reference table for task-specific guidance
- Include multi-tenant guidelines and site resolution flow
2026-06-05 23:46:15 -07:00

88 lines
2.9 KiB
Markdown

---
description: 'Use when writing or editing Svelte components, reactive state, props, effects, or event handlers for The Collective Hub. Enforces Svelte 5 runes syntax and forbids legacy Svelte 4 patterns.'
applyTo: '**/*.svelte'
---
# Svelte 5 Rules
## Always Use Runes
| Need | Use | Never |
| --------------------- | ------------------------ | --------------------------------- |
| Local state | `$state()` | `let x = 1` (mutable) |
| Computed value | `$derived(expr)` | `$: x = expr` |
| Side effects | `$effect(() => { ... })` | `onMount` (unless cleanup needed) |
| Component props | `let { x } = $props()` | `export let x` |
| Two-way bindable prop | `$bindable()` | — |
```svelte
<script lang="ts">
let { label, value = $bindable('') }: { label: string; value?: string } = $props();
let upper = $derived(value.toUpperCase());
</script>
```
## Event Handlers
Use direct HTML event attributes — not `on:` directive syntax.
```svelte
<!-- ✅ -->
<button onclick={handleClick}>Click</button>
<input oninput={(e) => (search = e.currentTarget.value)} />
<!-- ❌ -->
<button on:click={handleClick}>Click</button>
```
## Composition: Snippets over Slots
```svelte
<!-- ✅ -->
{#snippet row(item)}
<tr><td>{item.name}</td></tr>
{/snippet}
{@render row(movie)}
<!-- ❌ -->
<slot name="row" />
```
To accept snippets as props: `let { children } = $props()` + `{@render children()}`.
## Cross-Component State
- Prefer `setContext` / `getContext` for tree-scoped state
- Use `.svelte.ts` modules (with `$state` at module scope) for global/shared reactive state
- Avoid `svelte/store` (`writable`, `readable`, `derived`) in new code
## Always
- `<script lang="ts">` on every component
- Prefer `$derived` over `$effect` for computed values — `$effect` is for DOM/third-party side effects only
## Deprecated APIs
### `<svelte:component>` — Use component variables instead
`<svelte:component>` is **deprecated in Svelte 5**. Instead, assign a component constructor to a variable in the template using `{@const}` and render it directly as `<ComponentVar />`.
```svelte
<!-- ❌ Deprecated in Svelte 5 -->
<svelte:component this={iconMap[key]} size={12} />
<!-- ✅ Svelte 5 approach -->
{@const Icon = iconMap[key]}
{#if Icon}
<Icon size={12} />
{/if}
```
The `{#if}` guard ensures the component only renders when the variable is truthy, which also matches the previous runtime-guard behavior of `<svelte:component>`.
## Code Quality
### No `svelte-ignore` Suppression
`svelte-ignore` comments must NOT be used to suppress svelte-check errors or warnings. All accessibility (a11y), type, and other issues flagged by `svelte-check` must be fixed properly — never hidden behind a suppression comment.