---
name: Svelte Components
description: |
Svelte 5 component patterns for the Exceptionless SPA. Runes, reactivity, props,
events, snippets, component organization, and shadcn-svelte integration.
Keywords: Svelte 5, $state, $derived, $effect, $props, runes, onclick, snippets,
{@render}, reactive, component composition, shadcn-svelte
---
# Svelte Components
> **Documentation:** [svelte.dev](https://svelte.dev/docs) | Use `context7` for API reference
## Visual Validation with Chrome MCP
**Always verify UI changes visually** using the Chrome MCP:
1. After making component changes, use Chrome MCP to take a snapshot or screenshot
2. Verify the component renders correctly and matches expected design
3. Test interactive states (hover, focus, disabled) when applicable
4. Check responsive behavior at different viewport sizes
5. Default to the `/next` site path for verification
This visual validation loop catches styling issues, layout problems, and accessibility regressions that automated tests may miss.
## File Organization
### Naming Conventions
- **kebab-case** for all component files: `stack-status-badge.svelte`, `user-profile-card.svelte`
- Co-locate with feature slice, aligned with API controllers
### Directory Structure
```text
src/lib/features/
├── organizations/ # Matches OrganizationController
│ ├── components/
│ │ ├── organization-card.svelte
│ │ └── organization-switcher.svelte
│ ├── api.svelte.ts
│ ├── models.ts
│ └── schemas.ts
├── stacks/ # Matches StackController
│ └── components/
│ └── stack-status-badge.svelte
└── shared/ # Shared across features
└── components/
├── data-table/
├── navigation/
└── typography/
```
## Always Use shadcn-svelte Components
**Never use native HTML** for buttons, inputs, or form elements:
```svelte
Settings
```
## Runes
### $state - Reactive State
```svelte
```
### $derived - Computed Values
```svelte
```
### $effect - Side Effects
```svelte
```
## Props
```svelte
```
## Event Handling
Use `onclick` instead of `on:click`:
```svelte
(value = e.currentTarget.value)} />
```
## Snippets (Content Projection)
Replace `` with snippets. From [login/+page.svelte](src/Exceptionless.Web/ClientApp/src/routes/(auth)/login/+page.svelte):
```svelte
state.errors}>
{#snippet children(errors)}
{/snippet}
{#snippet children(field)}
Email
field.handleChange(e.currentTarget.value)}
/>
{/snippet}
```
## Class Merging
Use array syntax for conditional classes:
```svelte
Content
```
## Keyboard Accessibility
All interactive components must be keyboard accessible:
- Use `Button` component (provides focus handling automatically)
- Ensure custom interactions have `tabindex` and keyboard handlers
- Test with keyboard-only navigation
See [accessibility](accessibility/SKILL.md) for WCAG guidelines.
## Imports
```svelte
```
## References
- [shadcn-svelte](shadcn-svelte/SKILL.md) — UI component patterns and trigger snippets
- [accessibility](accessibility/SKILL.md) — WCAG guidelines and keyboard navigation