Skip to main content
Remix forms run through server-side actions by default, which is ideal for Formbase. Your action can forward the form data to Formbase and return a clean success or error state to the client. This avoids browser redirects and gives you full control over validation and UI feedback.
1

Create a Remix action

Forward the form data to Formbase from the server.
// app/routes/contact.tsx
import { json } from '@remix-run/node';

export async function action({ request }) {
  const formData = await request.formData();

  const response = await fetch('https://formbase.dev/s/YOUR_FORM_ID', {
    method: 'POST',
    body: formData,
  });

  if (!response.ok) {
    return json({ ok: false, message: 'Submission failed.' }, { status: 400 });
  }

  return json({ ok: true, message: 'Submitted!' });
}
Because this runs on the server, Formbase responds with JSON.
2

Build the form

import { Form, useActionData } from '@remix-run/react';

export default function ContactPage() {
  const actionData = useActionData();

  return (
    <Form method="post">
      <input name="name" placeholder="Name" required />
      <input name="email" type="email" placeholder="Email" required />
      <textarea name="message" required />
      <button type="submit">Send</button>
      {actionData?.message && <p>{actionData.message}</p>}
    </Form>
  );
}
Add encType="multipart/form-data" if you include file inputs.
Server actions are the recommended Remix pattern. Client-side fetch works too, but you must handle a 303 redirect response.