在 Next.js 中使用 Netlify Forms
Netlify Forms 在部署时通过扫描构建期间存在或生成的任何静态 HTML 文件,使用 表单标签属性的自动检测 (opens in a new tab)(例如:data-netlify)。
作为安全和反垃圾邮件措施,只有 Netlify 在部署时检测到的表单和字段名称才会被 Netlify 识别。提交表单时,表单目标 URL 也必须是静态文件。
然而,现代版本的 Next.js 不会生成完全静态的 HTML 页面,因为任何页面都可以在运行时重新验证。相反,相关页面在构建时预渲染,然后存储在 Next.js 的缓存中以供服务。这意味着您的 Next.js 页面(包括任何表单标签和属性)在部署时不会写入静态 HTML 文件,因此不能作为表单的目标页面。在这些页面中设置的与 Netlify Forms 相关的属性无效。
Netlify Forms 的变通方案
以下是解决此限制的一种方法:
-
在站点的
public目录中创建一个新的 HTML 文件。该文件仅用于部署时的表单检测。它可以有任何名称,例如public/__forms.html。 -
在该文件中,为所有 Netlify 表单和字段添加表单标签。在下面的示例中,请注意只需要最低限度的内容,因为用户根本不会看到这个 HTML 页面。
<html> <head></head> <body> <form name="feedback" data-netlify="true" hidden> <input type="hidden" name="form-name" value="feedback" /> <input name="name" type="text" /> <input name="email" type="text" /> <input name="message" type="text" /> </form> </body> </html> -
在您的动态页面或表单组件中,通过向您上面创建的静态 HTML 文件发送
POST请求来处理提交(使用上面的示例:/__forms)。 -
请求完成后,您应该显示成功通知或导航到另一个页面。以下是表单组件的简化示例:
"use client"; export function FeedbackForm() { const handleFormSubmit = async (event) => { event.preventDefault(); const formData = new FormData(event.target); await fetch("/__forms.html", { method: "POST", headers: { "Content-Type": "application/x-www-form-urlencoded" }, body: new URLSearchParams(formData).toString(), }); // 成功和错误处理 ... }; return ( <form name="feedback" onSubmit={handleFormSubmit}> <input type="hidden" name="form-name" value="feedback" /> <input name="name" type="text" placeholder="姓名" required /> <input name="email" type="text" placeholder="电子邮件(可选)" /> <button type="submit">提交</button> </form> ); }
在线演示
对于包含提交状态处理(成功、错误或待定)的更完整示例,请访问 在线演示 (opens in a new tab) 或探索 表单组件 (opens in a new tab) 和 所需静态文件 (opens in a new tab) 的代码。
防止静默失败
为了防止表单检测或提交的静默失败,当我们怀疑您的代码不兼容时,现在会触发故意的构建失败:
@netlify/plugin-nextjs@5 requires migration steps to support Netlify Forms. Refer to https://ntl.fyi/next-runtime-forms-migration for migration example.当满足以下两个条件时,会触发此失败:
- 适配器在您的 React 代码中发现了
netlify或data-netlify表单属性的使用(这些属性无效)。 - 在您的
public目录中未找到具有表单属性的静态 HTML 文件(从而表明您已实施了上述方法)。
跳过检查
如果您认为检查失败是不正确的,或者希望将问题的处理推迟到以后,您可以通过向站点添加值为 false 的 NETLIFY_NEXT_VERIFY_FORMS 环境变量来跳过此检查。