@fingerly/svelte exposes the JavaScript SDK through Svelte 5 runes. State lives in component context, so SvelteKit gets one identification per request tree rather than a shared module singleton.
Requirements
- Svelte 5. The package ships
.svelte.jsmodules that your Svelte build compiles. - A public key with your site in its allowed origins.
Install
npm install @fingerly/svelte
Set up the context
<script lang="ts">
import { setupFingerly } from '@fingerly/svelte'
let { children } = $props()
setupFingerly({ apiKey: 'fly_pk_us_production_…' })
</script>
{@render children()}
Call setupFingerly during component initialisation, in a <script> block, not in an event handler or an $effect.
Identify on an action
<script lang="ts">
import { useIdentify } from '@fingerly/svelte'
let { orderId } = $props()
const fingerly = useIdentify({ tag: () => 'checkout:' + orderId })
async function submit() {
const { requestId } = await fingerly.identify()
await submitOrder({ orderId, requestId })
}
</script>
<button onclick={submit} disabled={fingerly.isLoading}>
{fingerly.isLoading ? 'Checking…' : 'Pay now'}
</button>
{#if fingerly.error}<p>{fingerly.error.message}</p>{/if}
useIdentify
Accepts immediate (identify inside an $effect) and tag (a string or a getter). Returns reactive getters for the shared state plus identify, refresh and client.
useVerdict
<script lang="ts">
import { useVerdict } from '@fingerly/svelte'
const tor = useVerdict('tor', { min: 'high' })
</script>
{#if tor.matched}<p>This session arrives through Tor.</p>{/if}
The name and min accept values or getters, so they follow changing props. Verdict names are incognito, shields, tor, emulator, automation and farm.
Server rendering
immediate uses $effect, which does not run on the server. Calling identify() directly during server rendering rejects with FingerlyServerError.