Action Handler
Use Remix actions to forward form data to Spike:app/routes/contact.tsx
Copy
import { ActionFunctionArgs, json } from "@remix-run/node";
import { Form, useActionData } from "@remix-run/react";
export async function action({ request }: ActionFunctionArgs) {
const formData = await request.formData();
const res = await fetch("https://spike.ac/api/f/YOUR_FORM_SLUG", {
method: "POST",
body: formData,
});
if (res.ok) {
return json({ success: true });
}
return json({ success: false, error: "Failed to submit" });
}
export default function Contact() {
const data = useActionData<typeof action>();
return (
<Form method="post">
<input type="text" name="_gotcha" style={{ display: 'none' }} />
<div>
<label htmlFor="email">Email</label>
<input type="email" id="email" name="email" required />
</div>
<div>
<label htmlFor="message">Message</label>
<textarea id="message" name="message" required />
</div>
<button type="submit">Send</button>
{data?.success && <p>Thanks for your message!</p>}
{data?.error && <p>{data.error}</p>}
</Form>
);
}
With Loading State
Add loading state using Remix’suseNavigation:
app/routes/contact.tsx
Copy
import { ActionFunctionArgs, json } from "@remix-run/node";
import { Form, useActionData, useNavigation } from "@remix-run/react";
export async function action({ request }: ActionFunctionArgs) {
const formData = await request.formData();
const res = await fetch("https://spike.ac/api/f/YOUR_FORM_SLUG", {
method: "POST",
body: formData,
});
return json({ success: res.ok });
}
export default function Contact() {
const data = useActionData<typeof action>();
const navigation = useNavigation();
const isSubmitting = navigation.state === "submitting";
return (
<Form method="post">
<input type="email" name="email" required />
<textarea name="message" required />
<button type="submit" disabled={isSubmitting}>
{isSubmitting ? "Sending..." : "Send"}
</button>
{data?.success && <p>Thanks!</p>}
</Form>
);
}
Direct Submission
Or submit directly to Spike without a Remix action:Copy
<form action="https://spike.ac/api/f/YOUR_FORM_SLUG" method="POST">
<input type="hidden" name="_next" value="/thank-you" />
<input type="text" name="_gotcha" style="display:none" />
<input type="email" name="email" required />
<button type="submit">Subscribe</button>
</form>