Svelte

Essential Svelte syntax, components, reactivity, and best practices for building front-end applications.

frameworks
sveltejavascriptfrontendspa

Component Basics

<script>
  // Declare a reactive variable for user input
  let name = 'World';
</script>

<main>
  <!-- Display a greeting dynamically bound to the name variable -->
  <h1>Hello {name}!</h1>

  <!-- Input field with two-way binding to update the name variable -->
  <input bind:value={name} placeholder="Enter your name" />
</main>

<style>
  /* Ensure main content is styled for readability and alignment */
  main {
    font-family: Arial, sans-serif;
    text-align: center;
    padding: 2rem;
  }

  /* Style the heading with distinct color */
  h1 {
    color: #5a5ee0;
  }

  /* Input field design for better user experience */
  input {
    margin-top: 1rem;
    padding: 0.5rem;
    font-size: 1rem;
    border: 1px solid #ccc;
    border-radius: 4px;
  }
</style>

Event Handlers

<script>
  function greet() {
    alert('Welcome to Svelte!');
  }
</script>

<button on:click={greet}>Click me!</button>

Reactive Declarations

<script>
  let count = 0;

  // Reactive statements
  $: doubled = count * 2;
</script>

<p>Count: {count}</p>
<p>Doubled: {doubled}</p>

<button on:click={() => count++}>Increment</button>

Component Props

<!-- Greeting.svelte -->
<script>
  export let name;
</script>

<p>Hello {name}!</p>

<!-- App.svelte -->
<script>
  import Greeting from './Greeting.svelte';
</script>

<Greeting name="Svelte" />

Slots

<!-- Modal.svelte -->
<div class="modal">
  <slot></slot>
</div>

<style>
  .modal {
    padding: 1em;
    background: rgba(0, 0, 0, 0.8);
    color: white;
    border-radius: 8px;
  }
</style>

<!-- App.svelte -->
<script>
  import Modal from './Modal.svelte';
</script>

<Modal>
  <h2>Modal Content</h2>
  <p>This is a simple modal implementation using slots.</p>
</Modal>

Lifecycle Hooks

<script>
  import { onMount, onDestroy } from 'svelte';

  onMount(() => {
    console.log('Component is mounted');
  });

  onDestroy(() => {
    console.log('Cleaning up...');
  });
</script>

Transitions

<script>
  import { fade, slide } from 'svelte/transition';

  let visible = true;

  function toggle() {
    visible = !visible;
  }
</script>

<button on:click={toggle}>Toggle Visibility</button>

{#if visible}
  <p transition:fade>Hello with fade!</p>
  <div transition:slide>Sliding into view</div>
{/if}

Custom Stores

<script>
  import { writable } from 'svelte/store';

  // Custom writable store with built-in reset capability
  function createCounter() {
    const { subscribe, set, update } = writable(0);

    return {
      subscribe,
      increment: () => update(n => n + 1),
      decrement: () => update(n => n - 1),
      reset: () => set(0)
    };
  }

  const counter = createCounter();
</script>

<p>Count: {$counter}</p>
<button on:click={counter.increment}>+</button>
<button on:click={counter.decrement}>-</button>
<button on:click={counter.reset}>Reset</button>

Derived Stores

<script>
  import { writable, derived } from 'svelte/store';

  const firstName = writable('');
  const lastName = writable('');

  const fullName = derived(
    [firstName, lastName],
    ([$firstName, $lastName]) => `${$firstName} ${$lastName}`
  );
</script>

<input bind:value={$firstName} placeholder="First name">
<input bind:value={$lastName} placeholder="Last name">
<p>Full Name: {$fullName}</p>

Animations

<script>
  import { flip } from 'svelte/animate';

  let items = ['First', 'Second', 'Third'];

  function shuffle() {
    items = [...items].sort(() => Math.random() - 0.5);
  }
</script>

<button on:click={shuffle}>Shuffle</button>

<ul>
  {#each items as item (item)}
    <li animate:flip>{item}</li>
  {/each}
</ul>

Advanced Slots

<!-- Card.svelte -->
<script>
  export let title;
</script>

<div class="card">
  <header>
    <slot name="header">{title}</slot>
  </header>
  <main>
    <slot>
      <p>Default content goes here.</p>
    </slot>
  </main>
  <footer>
    <slot name="footer">
      <button>Default footer button</button>
    </slot>
  </footer>
</div>

<style>
  .card {
    border: 1px solid #ccc;
    border-radius: 8px;
    padding: 16px;
    max-width: 400px;
  }
  header, main, footer {
    margin-bottom: 8px;
  }
</style>
<!-- App.svelte -->
<script>
  import Card from './Card.svelte';
</script>

<Card title="Custom Card">
  <span slot="header">Custom Header</span>
  <p>Here is some custom content inside the card.</p>
  <div slot="footer">
    <button>Custom Button</button>
  </div>
</Card>