All articles Integration

SvelteKit Form Protection with Prynt Device Intelligence

SvelteKit’s form actions make it tempting to trust whatever the browser posts, but a bot fills a form action just as easily as a human. Device intelligence adds a verifiable visitor ID and a bot score to every submission so your server can tell them apart.

This guide adds Prynt to a SvelteKit form the idiomatic way: load the agent client-side, attach the event ID to the form, and verify it inside the action before writing anything. The pattern works the same whether you deploy to Node, Vercel, or Cloudflare, because the only server-side requirement is an outbound HTTPS call to the Prynt API.

Load the agent in the browser

The agent runs only in the browser, so initialize it in onMount. Loading is asynchronous and never blocks hydration.

<script>
  import { onMount } from 'svelte'
  import Prynt from '@prynt/js'

  let agent
  onMount(async () => {
    agent = await Prynt.load({
      apiKey: import.meta.env.VITE_PRYNT_KEY,
      endpoint: 'https://api.pryntid.com'
    })
  })
</script>

Keep a single agent per page. Re-loading on every interaction wastes work and produces no better signal.

Attach the event ID to your form

Call identify() when the user submits, then push the requestId into a hidden input so it rides along with the form action’s POST.

<form method="POST" action="?/signup" on:submit={attach}>
  <input name="email" type="email" />
  <input type="hidden" name="pryntId" bind:value={pryntId} />
  <button>Create account</button>
</form>

<script>
  let pryntId = ''
  async function attach() {
    const result = await agent.identify()
    pryntId = result.requestId
  }
</script>

The browser only collects the signal here. The decision happens on the server.

Verify inside the form action

Your +page.server.js action looks the event up with the secret key and branches on the result. This is the only place a security decision belongs.

// +page.server.js
export const actions = {
  signup: async ({ request }) => {
    const data = await request.formData()
    const id = data.get('pryntId')
    const res = await fetch(
      `https://api.pryntid.com/v1/events/${id}`,
      { headers: { Authorization: `Bearer ${process.env.PRYNT_SECRET}` } }
    )
    const event = await res.json()
    if (event.bot.result === 'automated') {
      return { status: 403, blocked: true }
    }
    // proceed: store event.visitorId with the account
  }
}

Storing visitorId against the account lets you catch one device creating many “unique” signups later. The available fields, including proxy and ASN data, are documented in the bot detection guide.

One subtlety with SvelteKit: because form actions support progressive enhancement, a submission can arrive without JavaScript having run, meaning no pryntId. Decide how to treat that case deliberately. For a low-risk newsletter form you might allow it; for account creation you should require the field and reject submissions that lack a verifiable event. Never fail open on the flows that matter, and log the missing-ID rate so you can spot bots deliberately disabling scripts.

Let Form Shield watch behavior

For extra coverage, guard the form element directly. Form Shield adds signals based on how the form was filled and submitted, catching scripted fills that produce a clean-looking POST.

agent.protectForm(document.querySelector('form'), {
  autoGuard: true,
  expectedScripts: ['latin']
})

expectedScripts flags submissions in unexpected writing systems, a reliable spam tell for Latin-audience sites. Form Shield and server verification are complementary: the first catches how the form was filled, the second confirms who filled it, and together they close the gap a single check would leave open.

Use the score, do not just block

A binary block frustrates real users caught by a flaky signal. Branch instead: high-confidence humans pass, low-confidence submissions get an email verification or a challenge. Because Prynt is a managed cloud service, the geolocation, VPN, and bot signals arrive without any infrastructure on your side, and the free tier covers early traffic.

Spin up a key, drop the agent into onMount, and verify inside your action. See the pricing and free plan to start, and your SvelteKit forms will reject bots before they ever hit your database.

Try it free

Prynt is device intelligence with a free tier — visitor IDs, bot & fraud Smart Signals, and behavioral biometrics, powered by a cross-site network. Start free.

Keep reading