Netlify
Netlify 表单

在 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 的变通方案

以下是解决此限制的一种方法:

  1. 在站点的 public 目录中创建一个新的 HTML 文件。该文件仅用于部署时的表单检测。它可以有任何名称,例如 public/__forms.html

  2. 在该文件中,为所有 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>
  3. 在您的动态页面或表单组件中,通过向您上面创建的静态 HTML 文件发送 POST 请求来处理提交(使用上面的示例:/__forms)。

  4. 请求完成后,您应该显示成功通知或导航到另一个页面。以下是表单组件的简化示例:

    "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 代码中发现了 netlifydata-netlify 表单属性的使用(这些属性无效)。
  • 在您的 public 目录中未找到具有表单属性的静态 HTML 文件(从而表明您已实施了上述方法)。

跳过检查

如果您认为检查失败是不正确的,或者希望将问题的处理推迟到以后,您可以通过向站点添加值为 falseNETLIFY_NEXT_VERIFY_FORMS 环境变量来跳过此检查。