Netlify
Netlify Forms

在 Next.js 中使用 Netlify Forms

Netlify Forms 通过在部署时扫描存在或在构建过程中生成的静态 HTML 文件,使用自动检测表单标签属性 (opens in a new tab)的方式(例如:data-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 文件(使用上面的示例:/__forms)发送 POST 请求来处理提交。

  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 需要执行迁移步骤以支持 Netlify Forms。请参考 https://ntl.fyi/next-runtime-forms-migration 获取迁移示例。

当同时满足以下两个条件时,会触发此失败:

  • 适配器在您的 React 代码中发现了 netlifydata-netlify 表单属性的使用(这些属性将不会生效)
  • 在您的 public 目录中未找到包含表单属性的静态 HTML 文件(表明您尚未按照上述方法实现)

跳过检查

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