#svelte #javascript #frontend

Day 13: Form Actions

Welcome to Day 13. Loading data is half the battle. Now let’s change it.

In SvelteKit, we use Form Actions.

The HTML Form

No useState needed. Just a standard form.

<!-- +page.svelte -->
<form method="POST" action="?/login">
  <input name="email" type="email" />
  <input name="password" type="password" />
  <button>Log in</button>
</form>

The Action (+page.server.ts)

Export an actions object.

export const actions = {
  login: async ({ request, cookies }) => {
    const data = await request.formData();
    const email = data.get('email');
    const password = data.get('password');

    if (!email || !password) {
      return { success: false, error: 'Missing fields' };
    }

    // interact with DB...
    cookies.set('session', 'abc-123', { path: '/' });

    return { success: true };
  }
};

Enhanced UI (use:enhance)

This works without JS! But with JS, we want progressive enhancement (no page reload).

<script>
  import { enhance } from '$app/forms';
</script>

<form method="POST" action="?/login" use:enhance>
  ...
</form>

SvelteKit handles the submission, updates data, and invalidates the load function automatically.

Challenge for Day 13

  1. Create a “Guestbook” page.
  2. load: Return list of messages.
  3. actions: Create default action to add a message.
  4. Form: Text input + Submit.
  5. Use use:enhance to make it snappy.

Solution:

// +page.server.ts
let db = []; // in-memory db

export function load() {
  return { messages: db };
}

export const actions = {
  default: async ({ request }) => {
    const data = await request.formData();
    db.push(data.get('message'));
  }
};

Tomorrow: The Final Project.