指南
Remix 联系表单(无需后端)
Remix 围绕服务器路由构建,但联系表单不一定要是其中之一。您可以使用简单的 form action 从浏览器直接 POST 到 Formhook - 或者,如果您想要 Remix 的渐进增强能力,用 useFetcher 来管理提交状态。
使用原生 HTML 表单
您不需要 API 路由。表单直接 POST 到 Formhook,您的框架完全不必接触提交内容。
contact.html
<form action="https://formhook.app/f/YOUR_API_KEY" method="POST">
<label>
Email
<input type="email" name="email" required />
</label>
<label>
Message
<textarea name="message" required></textarea>
</label>
<!-- honeypot: bots fill this; humans don't see it -->
<input type="text" name="_gotcha" tabindex="-1" autocomplete="off" hidden />
<!-- optional: send users to a thank-you page after a native POST -->
<input type="hidden" name="_redirect" value="https://example.com/thanks" />
<button type="submit">Send</button>
</form>或在 Remix 中通过 fetch 提交
如果您希望在不刷新整个页面的情况下获得客户端的成功/错误状态,使用这个版本。
app/routes/contact.tsx
// app/routes/contact.tsx
import { useFetcher } from "@remix-run/react";
export default function Contact() {
const fetcher = useFetcher();
const status = fetcher.state === "submitting" ? "sending" : fetcher.data?.ok ? "ok" : "idle";
if (status === "ok") return <p>Thanks - we'll be in touch.</p>;
return (
<fetcher.Form
method="post"
action="https://formhook.app/f/YOUR_API_KEY"
encType="application/x-www-form-urlencoded"
>
<input type="email" name="email" placeholder="Email" required />
<textarea name="message" placeholder="Message" required />
<input type="text" name="_gotcha" tabIndex={-1} hidden />
<button type="submit" disabled={status === "sending"}>
{status === "sending" ? "Sending…" : "Send"}
</button>
</fetcher.Form>
);
}工作原理
原生表单代码片段作为标准 HTML 表单工作 - Remix 的 <Form> 会把提交路由到一个 Remix action,但把 action 指向 formhook.app/f/YOUR_API_KEY 会完全绕过 Remix,将数据直接发送到 Formhook。useFetcher 版本保留了 Remix 的渐进增强,同时仍然在外部 POST:浏览器进行 XHR 提交,您可以获得 fetcher.state 来驱动 UI。
之后会发生什么
- 提交一秒内出现在您的 Formhook 仪表盘中。
- 推送通知会在每个启用它的设备上触发。
- 从仪表盘直接回复(Pro 及以上)- 您的 Remix 应用中无需 Resend/SendGrid 集成。
今天就上线您的 Remix 联系表单。
免费注册、创建表单、粘贴 API 密钥。五分钟搞定。
免费开始免费层:5 个表单 · 每月 250 次提交 · 无需信用卡。
Remix 联系表单 - 常见问题
- 我需要写 Remix action 函数吗?
- 不需要。把 form action 指向 formhook.app 会完全绕过 Remix 路由。如果您更倾向于为了日志或载荷整形而通过 Remix action 代理,您可以这样做 - 但不是必须的。
- 当 action 在不同的源上时,useFetcher 还能用吗?
- 可以。useFetcher 底层使用 fetch,因此只要您 Formhook 表单的允许来源列表包含您 Remix 应用的源,跨源请求就能工作。
- 它能与 Remix 的 `unstable_singleFetch` 或 React Router 7 一起工作吗?
- 可以 - 表单提交直接到 Formhook,因此不受 Remix 数据加载或路由变化的影响。
其他框架的指南
Migrating from Formspree? See how Formhook compares.