Caputchin
Panduan integrasi

Contoh integrasi frontend

Widget adalah elemen kustom standar, jadi ia berfungsi di setiap framework tanpa pembungkus untuk dipasang. Bentuknya selalu sama: muat paketnya sekali (integrasi sisi klien), render <caputchin-widget sitekey="cpt_pub_..."> di dalam formulirmu, dan baca field tersembunyi caputchin-token yang ia suntikkan saat pengunjung menuntaskan tantangan. Untuk sebuah game, tukar dengan <caputchin-game ... game="caputchin/games/leaf-memory">.

Contoh-contoh di bawah hanya berbeda dalam sintaks tiap framework dan satu kekhasan elemen-kustomnya.

HTML murni

Field yang disuntikkan ikut serta dalam POST formulir biasa, jadi tak ada yang perlu disambungkan:

<script src="https://cdn.jsdelivr.net/npm/@caputchin/widget@3/dist/widget.js"></script>

<form action="/contact" method="POST">
  <input name="email" type="email" required />
  <caputchin-widget sitekey="cpt_pub_..."></caputchin-widget>
  <button type="submit">Send</button>
</form>

React

Impor sekali saat startup, lalu baca field dari FormData saat submit:

import "@caputchin/widget";

export function ContactForm() {
  async function handleSubmit(e) {
    e.preventDefault();
    const data = new FormData(e.currentTarget);
    await fetch("/api/contact", {
      method: "POST",
      headers: { "content-type": "application/json" },
      body: JSON.stringify({ email: data.get("email"), token: data.get("caputchin-token") }),
    });
  }

  return (
    <form onSubmit={handleSubmit}>
      <input name="email" type="email" required />
      <caputchin-widget sitekey="cpt_pub_..." />
      <button type="submit">Send</button>
    </form>
  );
}

Jika kamu memakai TypeScript dengan React, deklarasikan kedua elemen sekali agar JSX menerimanya:

// caputchin.d.ts
import type { DetailedHTMLProps, HTMLAttributes } from "react";
declare module "react" {
  namespace JSX {
    interface IntrinsicElements {
      "caputchin-widget": DetailedHTMLProps<HTMLAttributes<HTMLElement> & { sitekey: string }, HTMLElement>;
      "caputchin-game": DetailedHTMLProps<HTMLAttributes<HTMLElement> & { sitekey: string; game?: string; games?: string }, HTMLElement>;
    }
  }
}

Bentuk declare module "react" ini khusus untuk JSX React. Di TypeScript murni elemen-elemennya hanyalah HTMLElement dan tak butuh deklarasi, dan framework lain di bawah mengetik elemen kustom dengan caranya sendiri, jadi kamu hanya butuh blok ini di proyek React.

Vue

Beri tahu kompiler Vue bahwa tag caputchin- adalah elemen kustom, agar ia tak mencoba menyelesaikannya sebagai komponen:

// vite.config.js
export default {
  plugins: [vue({ template: { compilerOptions: { isCustomElement: (tag) => tag.startsWith("caputchin-") } } })],
};
<script setup>
import "@caputchin/widget";
function onSubmit(e) {
  const data = new FormData(e.target);
  // send data.get("caputchin-token") to your backend
}
</script>

<template>
  <form @submit.prevent="onSubmit">
    <input name="email" type="email" required />
    <caputchin-widget sitekey="cpt_pub_..."></caputchin-widget>
    <button type="submit">Send</button>
  </form>
</template>

Svelte

Svelte merender elemen kustom apa adanya, tanpa konfigurasi:

<script>
  import "@caputchin/widget";
  function onSubmit(e) {
    const data = new FormData(e.currentTarget);
    // send data.get("caputchin-token") to your backend
  }
</script>

<form on:submit|preventDefault={onSubmit}>
  <input name="email" type="email" required />
  <caputchin-widget sitekey="cpt_pub_..."></caputchin-widget>
  <button type="submit">Send</button>
</form>

Angular

Tambahkan CUSTOM_ELEMENTS_SCHEMA ke modul atau komponen standalone agar Angular mengizinkan tag tak dikenal, dan impor paketnya sekali (di main.ts):

import { Component, CUSTOM_ELEMENTS_SCHEMA } from "@angular/core";
import "@caputchin/widget";

@Component({
  selector: "contact-form",
  schemas: [CUSTOM_ELEMENTS_SCHEMA],
  template: `
    <form (submit)="onSubmit($event)">
      <input name="email" type="email" required />
      <caputchin-widget sitekey="cpt_pub_..."></caputchin-widget>
      <button type="submit">Send</button>
    </form>
  `,
})
export class ContactFormComponent {
  onSubmit(e: Event) {
    const data = new FormData(e.target as HTMLFormElement);
    // send data.get("caputchin-token") to your backend
  }
}

Next.js

Kode React yang sama berfungsi. Elemen kustom dirender sebagai tag kosong selama server rendering dan ditingkatkan di klien begitu paketnya termuat, jadi tak ada penanganan khusus yang dibutuhkan selain mengimpor @caputchin/widget di sebuah komponen klien (atau memuat skrip CDN dengan next/script).

Lihat juga

Di halaman ini