Skip to content

Commit

Permalink
feat: lib
Browse files Browse the repository at this point in the history
  • Loading branch information
ghostdevv committed Sep 29, 2022
1 parent 6e313d7 commit 8c298a6
Show file tree
Hide file tree
Showing 6 changed files with 171 additions and 0 deletions.
46 changes: 46 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Svelte Turnstile

[Cloudflare's Turnstile](https://developers.cloudflare.com/turnstile/) is a new CAPTCHA alternative, this library allows you to easily integrate it into your svelte projects.

# Installing

```sh
npm install svelte-turnstile -D
```

# Using

The only required prop is the `siteKey` which you can get from [adding a site here](https://dash.cloudflare.com/?to=/:account/turnstile).

```html
<script>
import { Turnstile } from 'svelte-turnstile';
</script>

<Turnstile siteKey="0x4AAAAAAAAn8CCb_WenRWb-" />
```

## Props

| Prop | Type | Description | Required |
|------------|-------------------------------|-------------------------------------------------------------------------------|----------|
| `siteKey` | `string` | sitekey for your website ||
| `theme` | `'light' \| 'dark' \| 'auto'` | colour theme of the widget (defaults to auto) ||
| `action` | `string` | A string that can be used to differentiate widgets, returned on validation ||
| `cData` | `string` | A string that can attach customer data to a challange, returned on validation ||
| `tabIndex` | `number` | Used for accessibility (defaults to 0) ||

For more information about some of the props [checkout the Cloudflare Documentation](https://developers.cloudflare.com/turnstile/get-started/client-side-rendering/#configurations).

## Events

| Event | Data | Description |
|----------------------|---------------------|------------------------------------------------------------------------------|
| `turnstile-error` | `{}` | Emitted when a user fails verification |
| `turnstile-expired` | `{}` | Emitted when a challenge expires, this library will auto-renew the challenge |
| `turnstile-callback` | `{ token: string }` | Emitted when a user passes a challenge |

# Support

- Join the [discord](https://discord.gg/2Vd4wAjJnm)<br>
- Create a issue on the [github](https://github.com/ghostdevv/svelte-turnstile)
104 changes: 104 additions & 0 deletions src/lib/Turnstile.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
<script context="module" lang="ts">
declare global {
interface Window {
onloadTurnstileCallback: () => void;
turnstile: {
render: (
element: string | HTMLElement,
options: TurnstileOptions,
) => string;
reset: (widgetId: string) => void;
getResponse: (widgetId: string) => string | undefined;
};
}
}
interface TurnstileOptions {
sitekey: string;
action?: string;
cData?: string;
callback?: (token: string) => void;
'error-callback'?: () => void;
'expired-callback'?: () => void;
theme?: 'light' | 'dark' | 'auto';
tabindex?: number;
}
</script>

<script lang="ts">
import { createEventDispatcher } from 'svelte';
import { onMount } from 'svelte';
const dispatch = createEventDispatcher();
let loaded = false;
let mounted = false;
let node: HTMLElement;
let widgetId: string;
export let siteKey: string;
export let theme: TurnstileOptions['theme'] = 'auto';
export let action: string | undefined = undefined;
export let cData: string | undefined = undefined;
export let tabIndex = 0;
onMount(() => {
mounted = true;
return () => {
mounted = false;
loaded = false;
};
});
function loadCallback() {
console.log('Turnstile loaded');
loaded = true;
}
function error() {
dispatch('turnstile-error', {});
}
function expired() {
dispatch('turnstile-expired', {});
if (widgetId) {
window.turnstile.reset(widgetId);
}
}
function callback(token: string) {
dispatch('turnstile-callback', { token });
}
$: if (loaded && node) {
console.log('Rendering Turnstile');
widgetId = window.turnstile.render(node, {
'expired-callback': expired,
'error-callback': error,
callback,
sitekey: siteKey,
tabindex: tabIndex,
action,
theme,
cData,
});
}
</script>

<svelte:head>
{#if mounted}
<script
src="https://challenges.cloudflare.com/turnstile/v0/api.js"
on:load={loadCallback}
async></script>
{/if}
</svelte:head>

<div bind:this={node} />
9 changes: 9 additions & 0 deletions src/lib/events.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
declare namespace svelte.JSX {
interface HTMLProps<T> {
'onturnstile-error'?: (event: CustomEvent<{}>) => void;
'onturnstile-expired'?: (event: CustomEvent<{}>) => void;
'onturnstile-callback'?: (
event: CustomEvent<{ token: string }>,
) => void;
}
}
2 changes: 2 additions & 0 deletions src/lib/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import './events';
export { default as Turnstile } from './Turnstile.svelte';
1 change: 1 addition & 0 deletions src/lib/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default as Turnstile } from './Turnstile.svelte';
9 changes: 9 additions & 0 deletions src/routes/+page.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<script lang="ts">
import { Turnstile } from '$lib';
</script>

<Turnstile
siteKey="0x4AAAAAAAAn8CCb_WenRWb-"
on:turnstile-callback={(e) => alert(e.detail.token)}
on:turnstile-error={() => alert('error')}
on:turnstile-expired={() => alert('expire')} />

0 comments on commit 8c298a6

Please sign in to comment.