Remix Utils - v9.3.1
    Preparing search index...

    Module Server/Honeypot

    Note

    Install using bunx shadcn@latest add @remix-utils/honeypot-server and bunx shadcn@latest add @remix-utils/honeypot-react.

    Note

    This depends on react and @oslojs/crypto, and @oslojs/encoding.

    Honeypot is a simple technique to prevent spam bots from submitting forms. It works by adding a hidden field to the form that bots will fill, but humans won't.

    There's a pair of utils in Remix Utils to help you implement this.

    First, create a honeypot.server.ts where you will instantiate and configure your Honeypot.

    import { Honeypot } from "remix-utils/honeypot/server";

    // Create a new Honeypot instance, the values here are the defaults, you can
    // customize them
    export const honeypot = new Honeypot({
    randomizeNameFieldName: false,
    nameFieldName: "name__confirm",
    validFromFieldName: "from__confirm", // null to disable it
    encryptionSeed: undefined, // Ideally it should be unique even between processes
    });

    Then, in your app/root loader, call honeypot.getInputProps() and return it.

    // app/root.tsx
    import { honeypot } from "~/honeypot.server";

    export async function loader() {
    // more code here
    return json({ honeypotInputProps: honeypot.getInputProps() });
    }

    And in the app/root component render the HoneypotProvider component wrapping the rest of the UI.

    import { HoneypotProvider } from "remix-utils/honeypot/react";

    export default function Component() {
    // more code here
    return (
    // some JSX
    <HoneypotProvider {...honeypotInputProps}>
    <Outlet />
    </HoneypotProvider>
    // end that JSX
    );
    }

    Now, in every public form you want protect against spam (like a login form), render the HoneypotInputs component.

    import { HoneypotInputs } from "remix-utils/honeypot/react";

    function SomePublicForm() {
    return (
    <Form method="post">
    <HoneypotInputs label="Please leave this field blank" />
    {/* more inputs and some buttons * /}
    </Form>
    );
    }
    Note

    The label value above is the default one, use it to allow the label to be localized, or remove it if you don't want to change it.

    Finally, in the action the form submits to, you can call honeypot.check.

    import { SpamError } from "remix-utils/honeypot/server";
    import { honeypot } from "~/honeypot.server";

    export async function action({ request }) {
    let formData = await request.formData();
    try {
    honeypot.check(formData);
    } catch (error) {
    if (error instanceof SpamError) {
    // handle spam requests here
    }
    // handle any other possible error here, e.g. re-throw since nothing else
    // should be thrown
    }
    // the rest of your action
    }

    Classes

    Honeypot
    SpamError

    Interfaces

    HoneypotConfig
    HoneypotInputProps