# SvelteKit

A form action and $env/dynamic/private, which fails the build if you import it client side.

SvelteKit will not let you import a private environment variable into client code: the build fails rather than shipping the key. Use $env/static/private when the key is set at build time and $env/dynamic/private when it comes from the platform at runtime, which is the case on most adapters.

### Install

SvelteKit 2:
```bash
npm install @emails.sh/sdk
```

.env:
```bash
# .env, gitignored by the SvelteKit starter.
# The key comes from https://emails.sh/dashboard/api-keys.
EMAILSSH_API_KEY=esh_your_key_here
```

### A form action

src/routes/subscribe/+page.server.ts:
```ts
// src/routes/subscribe/+page.server.ts
import { fail } from '@sveltejs/kit';
import { env } from '$env/dynamic/private';
import { Emailssh } from '@emails.sh/sdk';
import type { Actions } from './$types';

export const actions: Actions = {
  default: async ({ request }) => {
    const data = await request.formData();
    const address = String(data.get('email') ?? '');
    if (!address.includes('@')) return fail(400, { message: 'Enter an email address.' });

    const mail = new Emailssh({ apiKey: env.EMAILSSH_API_KEY });

    try {
      const { id } = await mail.send({
        from: 'Acme <hello@acme.com>',
        to: [address],
        subject: 'Confirm your subscription',
        html: '<p>Click the link in this email to confirm.</p>',
        idempotencyKey: `subscribe-${address}`
      });
      return { id };
    } catch (err) {
      console.error('emails.sh refused the send', err);
      return fail(502, { message: 'Could not send that email. Try again in a minute.' });
    }
  }
};
```

src/routes/subscribe/+page.svelte:
```text
<!-- src/routes/subscribe/+page.svelte -->
<script lang="ts">
  let { form } = $props();
</script>

<form method="POST">
  <label for="email">Email</label>
  <input id="email" name="email" type="email" required />
  <button type="submit">Subscribe</button>
</form>

{#if form?.message}<p>{form.message}</p>{/if}
{#if form?.id}<p>Check your inbox.</p>{/if}
```

### On Cloudflare

With adapter-cloudflare the variable arrives through platform.env rather than the process environment, and $env/dynamic/private reads it for you. Set it with npx wrangler secret put EMAILSSH_API_KEY, and see /docs/cloudflare-workers for the Worker case.

---

Base URL: https://emails.sh/v1. Auth: `Authorization: Bearer esh_...`.
Whole API in one file: https://emails.sh/llms.txt. All documentation: https://emails.sh/docs.md.
