Files
2026-09-05 01:06:01 -03:00

185 lines
5.8 KiB
Plaintext

---
title: JavaScript
description: Learn how to integrate Duckity into your web application.
icon: SiJavascript
---
Welcome to the Duckity JavaScript SDK documentation! This guide will teach you how to install and
set up the SDK in no time.
The following SDKs depend on this one and provide specialized wrappers for different frameworks:
import { SiReact } from "@icons-pack/react-simple-icons";
<Cards>
<Card href="/sdks/react" title="React" icon={<SiReact />}>
Integrate client-side code with Duckity using the React SDK.
</Card>
</Cards>
## Quick Start
Before you can integrate Duckity into your application, you'll need to have the following:
1. An application,
2. CORS origins set up pointing to your application's origin(s),
3. At least one protection profile created in that application, and
4. The ID of the protection profiles to use
If you're missing either of those, head over to the [Duckity Dashboard](https://app.duckity.com) or
read the [Quick Start](/quick-start) guide to learn how to set those up.
Once you got those ready, follow these steps to get things running on your client:
### Install the SDK [step]
Follow these steps depending on your application:
<Tabs items={["Installed", "Via CDN"]}>
<Tab>
Run the following line in your terminal to install the Duckity SDK.
```package-install
@duckity/js
```
Then import it in your code:
```ts
import * as duckity from "@duckity/js";
```
</Tab>
<Tab>
If you're using the SDK from a static site, import it using a CDN like
[esm.sh](https://esm.sh/) instead.
```html
<script type="module">
// Using esm.sh
import * as duckity from "https://esm.sh/@duckity/js";
// Using jsdelivr.net
import * as duckity from "https://cdn.jsdelivr.net/npm/@duckity/js";
// Using UNPKG
import * as duckity from "https://unpkg.com/@duckity/js";
</script>
```
</Tab>
</Tabs>
### Solve a Challenge [step]
Once you have the SDK installed, you can request a challenge whenever you need it using
`duckity.solve()`.
```ts
import duckity from "@duckity/js";
/// Slow! Runs in a web worker, yet don't let it block code below unless necessary.
let solution: string = await duckity.solve(PROTECTION_PROFILE_ID);
```
### Validate a Challenge [step]
Send the solution token to your backend server any way you want. A header or parameter in a JSON
field will work.
Once in the server, you'll need the client's IP, their submitted solution token, the protection
profile's ID, and the application secret.
```ts
import * as duckity from "@duckity/js";
let applicationSecret: string;
let protectionProfileId: string;
let clientIp: string;
let solution: string;
let isValid = await duckity.validate(solution, clientIp, applicationSecret, protectionProfileId);
if (isValid) {
// Keep processing the request.
} else {
// Return an error to the client.
}
```
That's it! Now Duckity is protecting your endpoint. You can customize the behavior in the
[Duckity Dashboard](https://app.duckity.com).
## Advanced Usage
Solving a challenge on request works well for simple setups. However, UX can be greatly improved
changing a few settings and planning when to solve challenges.
### Asynchronous Challenge Solving
The challenge does not need to wait for the user to finish filling up a form or completing an action
to be issued. When you can guess the user will need a solution token, it is a good idea to start
computing it before the user needs it.
For example, if the user opens a login page, you can infer the user will need a challenge solved to
be able to attempt to log in. You can solve a challenge beforehand so that the user does not need to
wait.
```html
<!doctype html>
<html>
<head>
<style>
.hidden {
display: none;
}
</style>
</head>
<body>
<form id="form">
<input name="email" />
<input name="password" />
<button type="submit" id="submit-button">Log In</button>
<div id="submit-loading" class="hidden">Logging you in...</div>
</form>
<script type="module">
import * as duckity from "https://esm.sh/@duckity/js";
const PROTECTION_PROFILE_ID = "<your-protection-profile-id>";
const form = document.getElementById("form");
const submitButton = document.getElementById("submit-button");
const submitLoading = document.getElementById("submit-loading");
// A Promise<string>, it will solve a challenge in the background while the user logs
// in. Do not `await` it here, it will prevent the `form.addEventListener()` call from
// running until the challenge is solved, which takes some time.
let solutionPromise = duckity.solve(PROTECTION_PROFILE_ID);
form.addEventListener("submit", async (e) => {
e.preventDefault();
submitButton.classList.add("hidden");
submitLoading.classList.remove("hidden");
let solution = await solutionPromise;
// Do your stuff.
});
</script>
</body>
</html>
```
<Callout>
Solution tokens expire after the time set in the dashboard. In case of failure to validate, try
refreshing the challenge (calling `duckity.solve()` again).
</Callout>
## Contributing & License
All contributions are welcome to the SDK. Whether it's bug fixes, suggestions, new features,
documentation updates, or fixing a typo, if you think you can make this SDK better, feel free to
make a pull request in the [GitHub repository](https://github.com/duckity-com/sdks).
This SDK is licensed under the permissive MIT License, and so will be all contributions to the SDK.