Skip to content

Integrating ALTCHA's Widget into Your Astro Project

Here, we’ll explore the simplest method of integrating ALTCHA’s Widget into an Astro project.

If you’re unfamiliar with Astro, it’s a web framework designed for crafting content-driven websites. Before diving in, make sure you have Node.js installed. Astro also recommends using VS Code as your text editor and having access to a terminal for CLI operations.

Prerequisites

Ensure you have the following installed:

  • Node.js - Version 18.17.1 or 20.3.0, or higher.
  • Text editor - Astro recommends VS Code.
  • Terminal - Astro is accessed through its command-line interface (CLI).

Creating a New Astro Project

Let’s kick things off by creating a new Astro project. In your terminal, execute the following command:

Terminal window
npm create astro@latest -- --template minimal

Starting the Development Server

Navigate to your newly created Astro project directory in the terminal and initiate the development server:

Terminal window
npm run dev

This command will spin up a development server. Open the URL displayed in the output, and you should encounter a basic page featuring the text “Astro.”

Building a Contact Form

One common application for ALTCHA is embedding it within a contact form on a website. Let’s create an example of this.

Open the src/pages/index.astro file and begin by crafting a <form> element:

src/pages/index.astro
---
---
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<meta name="viewport" content="width=device-width" />
<meta name="generator" content={Astro.generator} />
<title>Astro</title>
</head>
<body>
<main>
<form method="POST">
<div>
<h3>Contact Form</h3>
</div>
<div class="field">
<label for="email">Email:</label>
<input type="email" name="email" id="email" required />
</div>
<div class="field">
<label for="email">Message:</label>
<textarea name="message" rows="4" required></textarea>
</div>
<div>
<button type="submit" class="button">Submit</button>
</div>
</form>
</main>
</body>
</html>

To improve the appearance of our form, let’s include some CSS styling directly within the same file:

src/pages/index.astro
---
---
<html lang="en">
<!-- our form from the previous step is here -->
</html>
<style is:global>
html {
background-color: #efefef;
font-family: system-ui, sans-serif;
}
input, textarea {
font-size: inherit;
padding: 0.5rem;
}
main {
max-width: 32rem;
margin: 0 auto;
padding: 1rem 0;
}
form {
background: white;
border: 1px solid gray;
border-radius: 0.5rem;
display: flex;
flex-direction: column;
gap: 1rem;
padding: 1rem;
}
.button {
font-size: 110%;
background: navy;
border: 0;
border-radius: 0.3rem;
color: white;
cursor: pointer;
padding: 0.75rem 1.5rem;
}
.field {
display: flex;
flex-direction: column;
gap: 0.4rem;
}
</style>

Installing the ALTCHA Widget

Now comes the exciting part: integrating the ALTCHA Widget into our form to enhance its security. Let’s install the official altcha package.

Navigate to your Astro project directory in the terminal and execute the following command:

Terminal window
npm install altcha

Adding the Widget

We’ll place the <altcha-widget> tag at the bottom of the form, just before the Submit button. Additionally, we need to import the altcha package within a new <script> tag:

src/pages/index.astro
---
---
<script>
import('altcha');
</script>
<html lang="en">
<head>
<!-- ... -->
</head>
<body>
<main>
<form method="POST">
<!-- the rest of the form is here -->
<div>
<altcha-widget
test
></altcha-widget>
</div>
<div>
<button type="submit" class="button">Submit</button>
</div>
</form>
</main>
</body>
</html>

We implemented two crucial modifications:

  1. We introduced a <script> tag to incorporate the altcha package. It’s vital to understand that the contents within the <script> tag in Astro execute in the browser. Since the widget isn’t server-renderable, importing the altcha package must occur on the client side.
  2. We included the <altcha-widget> within the form in a test mode. While this mode simulates functionality, it’s important to note that it’s solely for testing purposes.

Configure the Widget

To proceed with configuration swiftly, obtain a new API Key which you can acquire for free. Assuming you’re developing locally, utilize localhost as your website domain name.

If you prefer, you can also integrate with your own server. If you opt for this approach, designate your server’s URL as challengeurl.

After obtaining a new API Key, insert both the key and the secret into the head of your file:

src/pages/index.astro
---
const ALTCHA_API_KEY = "ckey_...";
const ALTCHA_API_SECRET = "csec_...";
---

Then, replace the test attribute with challengeurl:

src/pages/index.astro
<altcha-widget
challengeurl={`https://eu.altcha.org/api/v1/challenge?apiKey=${ALTCHA_API_KEY}`}
></altcha-widget>

Now, upon verifying yourself by clicking “I’m not a robot”, you should observe a request being sent to ALTCHA’s API, and the verification should succeed. If you encounter an error from the API, please refer to the API errors documentation for guidance.

Handling Form Submissions

To enable form submissions, we need to make some adjustments to the Astro project configuration.

For detailed information, consult the Astro Forms documentation.

Adding the node Adapter

Navigate to your Astro project directory in the terminal and execute the following command:

Terminal window
npx astro add node

This command installs the node adapter into your project. Confirm any automatic configuration changes.

Adding a Submission Handler

Let’s incorporate a POST request handler at the head of the file:

src/pages/index.astro
---
const ALTCHA_API_KEY = "ckey_...";
const ALTCHA_API_SECRET = "csec_...";
if (Astro.request.method === "POST") {
try {
const data = await Astro.request.formData();
} catch (error) {
if (error instanceof Error) {
console.error(error.message);
}
}
}
---

This code snippet sets up a handler for POST requests. It attempts to retrieve form data asynchronously.

Installing the altcha-lib Package

The official altcha-lib package is compatible with Node.js, Bum, Deno, and various other modern runtimes like Cloudflare workers. It contains helpful functions for payload verification.

Navigate to your Astro project directory in the terminal and run:

Terminal window
npm install altcha-lib

Verifying ALTCHA Payload

Incorporate the following changes at the head of the file:

src/pages/index.astro
---
import { verifySolution } from "altcha-lib";
const ALTCHA_API_KEY = "ckey_...";
const ALTCHA_API_SECRET = "csec_...";
if (Astro.request.method === "POST") {
try {
const data = await Astro.request.formData();
const altchaPayload = data.get("altcha")?.toString();
if (!altchaPayload) {
throw new Error("Altcha payload missing.");
}
if (await verifySolution(altchaPayload, ALTCHA_API_SECRET)) {
console.log('Verification successful', Object.fromEntries(data))
// TODO: process data
} else {
console.log('Verification failed')
// TODO: report failure to user
}
} catch (error) {
if (error instanceof Error) {
console.error(error.message);
}
}
}
---

This snippet includes the verifySolution function call, which verifies the received altcha payload from the form data using the provided API Key secret.

Upon successful verification, you can proceed to store or process the submitted data. This tutorial doesn’t delve into the specifics of data handling.

It’s essential to note that verifySolution doesn’t perform any HTTP requests. Instead, it conducts verification cryptographically using the HMAC signing mechanism.

Conclusion

Integrating ALTCHA into your website is straightforward. Utilize our official packages altcha and altcha-lib to kickstart your integration, or explore the community integrations if you’re using a different stack.

For a complete working example, refer to the repository.