Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/khuongduybui/fresh-turnstile
Cloudflare Turnstile plugin for Deno Fresh
https://github.com/khuongduybui/fresh-turnstile
cloudflare fresh plugin turnstile
Last synced: 14 days ago
JSON representation
Cloudflare Turnstile plugin for Deno Fresh
- Host: GitHub
- URL: https://github.com/khuongduybui/fresh-turnstile
- Owner: khuongduybui
- License: mit
- Created: 2022-10-04T02:24:30.000Z (over 2 years ago)
- Default Branch: main
- Last Pushed: 2023-07-23T01:48:24.000Z (over 1 year ago)
- Last Synced: 2025-01-18T10:50:13.285Z (20 days ago)
- Topics: cloudflare, fresh, plugin, turnstile
- Language: TypeScript
- Homepage: https://fresh-flowbite.deno.dev/
- Size: 69.3 KB
- Stars: 2
- Watchers: 3
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# fresh-turnstile
[Cloudflare Turnstile](https://www.cloudflare.com/lp/turnstile/) [plugin](https://fresh.deno.dev/docs/concepts/plugins) for
[Deno Fresh](https://fresh.deno.dev/).## Installation
First of all, create [your fresh app](https://fresh.deno.dev/docs/getting-started/create-a-project).
Add Turnstile to your `import_map.json`.
```json
{
"imports": {
"$turnstile/": "https://deno.land/x/[email protected]/"
}
}
```Consume the Turnstile plugin in your app's `main.ts`.
```ts
import { TurnstilePlugin } from "$turnstile/index.ts";await start(manifest, {
plugins: [
// ...
TurnstilePlugin(),
// ...
],
});
```## Client-side Rendering
### Implicit Rendering
#### Protecting a form
Add `` inside your form. A hidden input named `cf-turnstile-response` will be added to your form with the token value once a
response is received from Turnstile. See the instructions in the [server-side validation](#server-side-validation) section further below for easy server-side
handling.Please note that if you use AJAX / fetch to submit the form, you will need to call `getTurnstileAsync()` to get access to the `turnstile` object and then
invokes `turnstile.reset(widgetId)` to get a fresh token. See the section on [explicit rendering](#explicit-rendering) below for more instructions on how to get
access to the `turnstile` object. The `id` attribute you provide to `` gets passthrough directly to the widget, so you can use that ID as
`widgetId` in `turnstile.getResponse(widgetId)` and `turnstile.reset(widgetId)`.#### Protecting a page
You can add the `callback`, `errorCallback`, and `expiredCallback` props on `` and dynamically handle these events.
The following code sample displays the response token on the page when it's received from Turnstile.
```tsx
import { useSignal } from "@preact/signals";
// ...
const response = useSignal("Waiting for validation...");
// ...
response.value = token} />{response}
```**Note**: for implicit rendering, the [official docs](https://developers.cloudflare.com/turnstile/get-started/client-side-rendering/#configurations) describe
`data-callback`, `data-error-callback`, and `data-expired-callback` as strings (function names) that get invoked later. However, this plugin makes uses of
`useId` and `useEffect` hooks to allow you to provide the callable props directly to `callback`, `errorCallback`, and `expiredCallback`.#### Disable implicit rendering
Add the `disableImplicitRendering` option to your plugin declaration. (See the [installation](#installation) section above again for more information.)
```ts
await start(manifest, {
plugins: [
// ...
TurnstilePlugin({ disableImplicitRendering: true }),
// ...
],
});
```Once you have disabled implicit rendering, see the next section to [explicitly render](#explicit-rendering) your Turnstile widgets.
### Explicit Rendering
You can get the `turnstile` global object from inside a `useEffect` hook like this:
```tsx
import { useEffect } from "preact/hooks";
import { getTurnstileAsync } from "$turnstile/plugin.ts";
//...
useEffect(() => {
getTurnstileAsync().then((turnstile) => {
// console.log(turnstile);
});
});
```Or you can directly use the `useTurnstileEffect` hook:
```tsx
import { useTurnstileEffect } from "$turnstile/plugin.ts";
// ...
useTurnstileEffect((turnstile) => {
// console.log(turnstile);
});
```Once you have got ahold of the `turnstile` object within an effect hook, you can now call `turnstile.render(...)` similar to how it is shown in
[official docs](https://developers.cloudflare.com/turnstile/get-started/client-side-rendering/#explicitly-render-the-turnstile-widget).## Server-side Validation
`fresh-turnstile` provides a default POST handler for easy server-side form validations.
You may use it like this in your route:
```tsx
import { CfTurnstileValidationResult, generatePostHandler } from "$turnstile/handlers/CfTurnstileValidation.ts";import Page from "$flowbite/components/Page.tsx";
export const handler = { POST: generatePostHandler(cf_turnstile_secret_key) };
export default function CfTurnstileValidation({ data }: PageProps) {
/* 3 scenarios can occur here:
* 1. data is null => the form was not submitted correctly, or the secret key was not provided.
* 2. data.success is false => the form was submitted correctly, but validation failed. data["error-codes"] should be a list of error codes (as strings).
* 3. data.success is true => the form was submitted correctly and validated successfully. data.challenge_ts and data.hostname should be available for inspection.
*/
}
```## A note about versioning
For now, the versions are `a.b.c-x.y.z` where `a.b.c` is the plugin version and `x.y.z` is the supported Turnstile API version. For example, `0.0.1-0` is the
initial release of plugin, which supports Turnstile API v0.All tags starting with `0.0.` are **mutable**. Expect breaking changes! Starting from `0.1.`, tags will be **immutable**. However, still expect breaking
changes. Starting from `1.`, semver will kick in and there will be no breaking changes until `2.`.