@foundrykit/advanced-forms-plugin

中文文档
1.16.2发布于 2026/11/09MITTypeScriptES Module构建来源已验证近 30 天下载 2437

有效载荷 CMS 3 的多步查询表插件

中文使用文档
文档目录24 节
  1. 特征
  2. 安装
  3. 快开始
  4. 插件选项
  5. 垃圾邮件保护(ReCAPTCHA v3)
  6. 收款
  7. 表单( E) forms (中文(简体) )
  8. 提交资料 form-submissions (中文(简体) )
  9. 字段类型
  10. 旅行日期(可选入)
  11. 地址字段
  12. 提交行动
  13. (原始内容存档于2013-10-12) (英语). REST API
  14. GET /api/form-data/:slug
  15. POST /api/form-submit/:formSlug
  16. 前端用途
  17. 服务器组件——获取窗体数据
  18. 客户部分——提供表格
  19. 验证
  20. Hook — 自定义格式 UI
  21. 自定义字段块
  22. 结构概览
  23. 发展
  24. 释放

@ foundrykit/ 高级形式- 插件

多步骤窗体插件 有效载荷CMS 3。在您的管理面板上添加一个窗体构建器,其中包含11个内置的字段类型,可配置的提交动作,以及用于前端的即时反应组件.

特征

  • 多步骤形式 ——将字段组织成有可选图标和进度指标的已命名步骤
  • reCAPTCHA v3 (英语) · 每种形式的可选、无形的垃圾邮件保护
  • 12个外地类型 ——文本,电子邮件,电话,文本区域,复选框,收音机组,复选框组,选取,编号,日期,文件上传,地址(并带有后码查询)
  • 提交行动 ——发送电子邮件,显示确认消息,或提交后重定向(每个表单多动作,按顺序执行)
  • 两集 —— 说 forms 财务报告和审定财务报表 form-submissions 自动添加到您的有效载荷配置
  • (原始内容存档于2013-10-12) (英语). REST API ——通过有效载荷自定义终点获取窗体数据并提交表格
  • 前端组件 —— 说 <EnquiryForm> 以内置步骤导航和验证来反应客户端组件
  • 完全定制 ——禁用、替换或添加字段块类型;重命名收藏 satters

安装

pnpm add @foundrykit/advanced-forms-plugin

同伴依赖关系 (如尚未安装)

pnpm add payload react react-hook-form @radix-ui/react-popover

快开始

// payload.config.ts
import { formPlugin } from '@foundrykit/advanced-forms-plugin'
import { buildConfig } from 'payload'

export default buildConfig({
  // Configure your email adapter here — the plugin uses payload.sendEmail
  // for the `sendEmail` submission action.
  // email: nodemailerAdapter({ ... }) or resendAdapter({ ... }), etc.
  plugins: [formPlugin({})],
  // ...rest of your config
})

这个 sendEmail 提交动作使用有效载荷内置 payload.sendEmail,哪个 常驻裁军谈判会议代表 电子邮件适配器 你们 在有效载荷配置上配置 。 不需要插件级电子邮件处理器 .


插件选项

formPlugin(options: FormPluginConfig)
选项类型默认说明
disabledbooleanfalse注册收藏但跳过添加端点
baseUrlstring''在构建时将基础 URL 准备形成 API URL(例如. https://example.com(中文(简体) )
mediaCollectionstring'media'显示您收藏的媒体, 用于步骤图标上传
collections.formsstring'forms'窗体收藏的标签
collections.submissionsstring'form-submissions'提交文件收集的屏障
labels.formsstring'Form'表单的 Singula 管理标签
labels.submissionsstring'Form Submission'提交文件的 Singula 管理标签
fieldsFieldsConfig全部内置控制窗体构建器中可用的字段块类型——见 自定义字段块

垃圾邮件保护(ReCAPTCHA v3)

传出 a captcha 配置和每个表单的提交端点都需要验证 {\fn黑体\fs22\bord1\shad0\3aHBE\4aH00\fscx67\fscy66\2cHFFFFFF\3cH808080}是CAPTCHA v3 代币 别管它了,或者把钥匙放出去,什么也没有 更改: 没有装入脚本, 不需要符号 .

formPlugin({
  captcha: {
    siteKey: process.env.RECAPTCHA_SITE_KEY,
    secretKey: process.env.RECAPTCHA_SECRET_KEY,
    minScore: 0.5,        // optional, default 0.5
    action: 'form_submit' // optional, default 'form_submit'
  },
})

没有别的东西可以窃听. GET /api/form-data/:slug 广告 站点密钥 (按设计公开)浏览器, EnquiryForm 薄荷每服一剂, 财务报告和审定财务报表 POST /api/form-submit/:formSlug 在表单平之前验证一下 装入。 这个 密钥永不离开服务器 - 综合测试 声称表格答复中未提及.

得分,不是挑战. v3 是隐形的: 它返回 0.0- 1. 0 而您选择 截断。 调色板 minScore 从reCAPTCHA控制台 一旦你能看到真实 交通;太高无声地拒绝真正的人.

故意没打开. 如果Google无法访问, 或秘密是 错误, 允许提交, 原因会被记录为错误 。 封锁 将会丢弃真实的询问 时间长度的断电或 错位,比垃圾邮件还要贵 失踪或 拒绝的代号仍然很困难 403 仅限 基础设施 失败是 原谅我 注意日志 [forms] captcha could not be verified。 。 。 .

将站点密钥与每个为表格服务的域进行注册,包括 localhost 或每个当地提交文件都无法核实.


收款

表单( E)forms(中文(简体) )

存储构成定义. 可公开读取;创建/更新/删除需要认证.

每个表格文档有:

  • 标题 — 显示名称
  • 弹片 ——API中使用的独特标识符(例如. contact-form(中文(简体) )
  • 步骤 ——一个或多个步骤,每个步骤都有标题,可选图标,以及字段块列表
  • 额外内容 ——表上或表下可选的丰富文本
  • 行动 - 在成功提交后执行的一项或多项行动

提交资料form-submissions(中文(简体) )

每个划界案一份。 存储 :

  • 标题 ——谁寄出:答案取名 name, (中文(简体) ), full-name 或者说 first-name + 键 last-name,或者电子邮件,或者日期。 用作页面标题.
  • 表单 ——与父母形式的关系
  • 提交日期 — ISO 时间戳
  • 数据 ——提交字段值的密钥/值对
  • 元数据 —— 说 userAgent, (中文(简体) ), ip, (中文(简体) ), referrer 从请求中捕获

在管理员中,划界案的答案在表格本身的问题下显示,按步骤分组, 选项值显示为标签和电话、计数器和地址答案. 编辑 在Answers卡上将文本解答变为输入,选择解答变为下拉,所以 工作人员可以在重发前修补错误的电子邮件;更改保存时保留. 电话柜台 和地址答案不能在那里编辑。 表格、日期和a 细节 纸牌( 页面) 来源,IP,浏览器和提交上下文)是只读的.

站点可以以相同的卡片样式显示自己的提交字段 SubmissionPanel 从 @foundrykit/advanced-forms-plugin/rsc作为田园 admin.components.Field数字 :

import { SubmissionPanel } from '@foundrykit/advanced-forms-plugin/rsc'

export const NotesField = ({ data }) => (
  <SubmissionPanel
    heading="Notes"
    id="notes"
    groups={[{ items: [{ label: 'Follow-up', value: data?.followUp ?? '' }] }]}
  />
)

升级到 Postgres 的提交视图 : 页:1 title 列是新建的,所以添加一个 移徙(ALTER TABLE "form_submissions" ADD COLUMN "title" varchar;重新生成导入 地图。 旧的呈文读取标题直到下次保存为止.


字段类型

块状弹片说明
text单行文本输入( 支持) half 宽度)
email电子邮件地址输入
phone电话号码输入
textarea多行文本( 可配置) rows(中文(简体) )
checkbox单个布尔复选框
radioGroup从列表中选择单一选项( :row 或者说 grid (布局)
checkboxGroup从列表中选择多个选项( E)row 或者说 grid (布局)
select下拉选择
number可选数字输入 min, (中文(简体) ), max, (中文(简体) ), step
date可选取日期者 min编号 :max
file文件上传到有效载荷收藏( 可配置) accept, (中文(简体) ), maxSizeMB(中文(简体) )
address英国邮政编码查询地址( 可配置) defaultCountry, (中文(简体) ), showLine2, (中文(简体) ), lookupLabel(中文(简体) )

所有字段块共享这些基属性: name, (中文(简体) ), label, (中文(简体) ), required, (中文(简体) ), tooltip。 。 。 .

旅行日期(可选入)

"你想什么时候旅行?":一个日历面板,游客在那里挑选 一个月 (单位:一年) 月按钮)或 确切的日期 (日历,通过 react-day-picker) (中文(简体) ). 这是我们自己的 面板而不是本地选择和日期输入,所以网站可以标出它: enquiry-field__calendar* 课程。 它不在默认的集中, 所以添加到插件中不会 更改任何现有网站的计划。 登记,然后在邮递表中添加一个迁移:

import { formPlugin, TravelDateBlock } from '@foundrykit/advanced-forms-plugin'

formPlugin({ fields: { travelDate: { block: TravelDateBlock } } })

答案为 2027-08 或者说 2027-08-14 ,并在提交页面上显示为 "2027年8月"或"2027年8月14日". parseTravelDate(value) 给它覆盖的第一天和最后一天 (单位:千美元)from编号 :to,准确日期的同一天)和那个标签,用于映射一个客户关系管理系统.

要问“你灵活吗?” 只要不灵活就需要约会,就加上一个是 / 无字段和 给予旅行日期可见度规则: 规则匹配时需要此字段,灵活 等于 no。 。 。 .

地址字段

存储一个复合值 - { line1, line2, city, county, postcode, country } —— 说 在呈文中连载到JSON,同样的方式 phone 存储 { country, number, e164 }。 。 。 .

检查由 邮政编码.io:免费,没有 API 密钥, 没有人每通电话开账单,所以球场可以不看任何公开形式 一个配额。 它只解决其城镇、县和国家的邮政编码问题——它确实如此 不返回一个房地列表,所以街道线总是被打入. 手动条目是 从未被屏蔽,使字段能够用于非英国地址和何时 寻取相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相.

A 类 所需经费 地址需要街道行和邮政编码:单是邮政编码 无法交付, 和搜索永远无法提供街道。 重用浏览 与导出助手的表格外 :

import { lookupPostcode } from '@foundrykit/advanced-forms-plugin/client'

const result = await lookupPostcode('SW1A 1AA')
// { status: 'ok', address: { postcode, city, county, country } }
// | { status: 'notFound' } | { status: 'error' }

提交行动

每个窗体配置一个或多个动作。 他们按出现顺序执行.

块说明
sendEmail通过电子邮件发送邮件 payload.sendEmail (使用您的有效载荷) 电子邮件适配器) (中文(简体) ). 主题支持 {{fieldName}} 内插.
confirmationMessage返回 API 响应中的 Lexical 丰富文本消息,用于显示前端 .
redirect回返a redirectUrl 在API响应中。 前端组件处理导航.

(原始内容存档于2013-10-12) (英语). REST API

两个端点都登记在有效载荷 API 根上(/api (默认情况下).

GET /api/form-data/:slug

以弹片取出窗体文档.

回应: 全文 FormDocument 贾森.

POST /api/form-submit/:formSlug

提交窗体的字段数据.

请求机构 :

{
  "data": { "name": "Alice", "email": "[email protected]" },
  "metadata": { "referrer": "https://example.com/about" }
}

成功反应200:

{
  "success": true,
  "actions": {
    "confirmationMessage": { /* Lexical rich-text node */ },
    "redirectUrl": "/thank-you"
  }
}

校验出错的答复( E)422:

{
  "success": false,
  "errors": [{ "field": "email", "message": "Email is required" }]
}

前端用途

服务器组件——获取窗体数据

从 @foundrykit/advanced-forms-plugin/rsc数字 :

import { fetchForm } from '@foundrykit/advanced-forms-plugin/rsc'

export default async function ContactPage() {
  const form = await fetchForm({ slug: 'contact-form' })
  return <ContactForm form={form} />
}

fetchForm 选项:

选项类型默认说明
slugstring所需经费要获取的窗体 sattle
baseUrlstring''覆盖 API 基础 URL
formsSlugstring'forms'覆盖 URL 路径中使用的表单收藏 sattle

客户部分——提供表格

从 @foundrykit/advanced-forms-plugin/client数字 :

'use client'

import { EnquiryForm } from '@foundrykit/advanced-forms-plugin/client'
import type { FormDocument } from '@foundrykit/advanced-forms-plugin'

export function ContactForm({ form }: { form: FormDocument }) {
  return (
    <EnquiryForm
      form={form}
      onSuccess={(result) => console.log('submitted', result)}
      onError={(err) => console.error(err)}
    />
  )
}

EnquiryForm 道具 :

Prop类型默认说明
formFormDocument所需经费表单数据由 fetchForm
apiBasestring''提交端点的基础 URL
classNamestring—— 说适用于根元素的 CSS 类
onSuccess(result: SubmitResult) => void—— 说在成功提交后调用
onError(error: SubmitError) => void—— 说当服务器返回验证错误时调用
additionalContentReactNode—— 说表格上或下的额外内容(尊重 additionalContent.position 设置)
resolverResolver<Record<string, unknown>>—— 说可选反应-hook-form 解析器(例如. zodResolver(schema)) (中文(简体) ). 与每个外地管理员的规则合并.

验证

每个字段都会暴露一个管理员 验证 组 : requiredMessage, (中文(简体) ), minLength 编号 : maxLength 编号 : pattern 编号 : patternMessage (用于文本形状) 字段)和 min 编号 : max 编号 : minMessage 编号 : maxMessage (用于数字字段) 和多场比赛总数。 这些规则通过 buildFieldRules 帮助者,也从 /client 用于: 自定义字段组件.

对于更丰富的跨域逻辑,通过形式级解析器. 插件确实如此 没有 捆绑 zod 或者说 @hookform/resolvers 安装在您的应用程序中:

pnpm add zod @hookform/resolvers
'use client'

import { EnquiryForm } from '@foundrykit/advanced-forms-plugin/client'
import { zodResolver } from '@hookform/resolvers/zod'
import { z } from 'zod'

const schema = z
  .object({
    travelKnown: z.enum(['yes', 'no']).optional(),
    travelPlans: z.string().optional(),
  })
  .passthrough()
  .superRefine((data, ctx) => {
    if (data.travelKnown === 'no' && !data.travelPlans) {
      ctx.addIssue({
        path: ['travelPlans'],
        code: 'custom',
        message: 'Tell us a bit about what you’re looking for',
      })
    }
  })

export function ContactForm({ form }) {
  return <EnquiryForm form={form} resolver={zodResolver(schema)} />
}

每个外地管理员的规则和解决者一起运行——任一来源都可以标出 无效的字段,并逐个进行验证(goNext)尊重两者.

Hook — 自定义格式 UI

如果您需要完全控制窗体 UI, 请使用 useEnquiryForm 直接 :

'use client'

import { useEnquiryForm } from '@foundrykit/advanced-forms-plugin/client'

export function MyCustomForm({ form }) {
  const { currentStep, totalSteps, stepData, form: rhf, goNext, goBack, submit, isSubmitting } =
    useEnquiryForm({ form, apiBase: '' })

  // render whatever you like
}

自定义字段块

这个 fields 选项:

formPlugin({
  fields: {
    // disable a built-in type
    file: false,

    // replace a built-in type with your own block
    text: { block: myCustomTextBlock },

    // add a new type
    budgetRange: { block: BudgetRangeBlock },
  },
})

内置弹道: text, (中文(简体) ), email, (中文(简体) ), phone, (中文(简体) ), textarea, (中文(简体) ), checkbox, (中文(简体) ), radioGroup, (中文(简体) ), checkboxGroup, (中文(简体) ), select, (中文(简体) ), number, (中文(简体) ), date, (中文(简体) ), file, (中文(简体) ), address。 。 。 .


结构概览

src/
├── index.ts                  # Plugin entry — merges collections and endpoints into Payload config
├── types.ts                  # All shared TypeScript types (field blocks, FormDocument, plugin config)
├── collections/
│   ├── Forms.ts              # createFormsCollection factory
│   └── Submissions.ts        # createSubmissionsCollection factory
├── blocks/
│   ├── fields/               # One file per built-in field block type
│   └── submissionActions/    # SendEmail, ConfirmationMessage, Redirect blocks
├── endpoints/
│   ├── fetchFormHandler.ts   # GET /api/form-data/:slug
│   └── submitFormHandler.ts  # POST /api/form-submit/:formSlug — validates, stores, fires actions
├── components/
│   └── EnquiryForm/          # React client component and useEnquiryForm hook
├── utilities/
│   ├── fetchEnquiryForm.ts   # fetchForm — RSC utility wrapping the fetch endpoint
│   ├── buildFormURL.ts       # URL builder for the form-data endpoint
│   └── sanitizeSubmission.ts # Sanitises raw form data before storage
└── exports/
    ├── client.ts             # @foundrykit/advanced-forms-plugin/client exports
    └── rsc.ts                # @foundrykit/advanced-forms-plugin/rsc exports

插件遵循标准的有效载荷插件模式 : formPlugin(options) 返回接收并返回有效载荷的函数 Config 对象。 集合和端点的添加使用分布式语法来避免覆盖已存在的配置.


发展

pnpm dev        # Start the dev app at http://localhost:3000
pnpm test       # Run unit + integration + e2e tests
pnpm build      # Compile to dist/

复制 dev/.env.example 改为 dev/.env 设置 DATABASE_URL 财务报告和审定财务报表 PAYLOAD_SECRET 运行前 dev。 。 。 .

释放

运行 pnpm release 打开 prod。它撞倒了版本,更新了更改日志并推出一个 v* 标签. 标签触发器 .github/workflows/publish.yml,通过信任的方式发布到 npm 发布,所以没有npm令牌在当地或GitHub存储.

版本与发布记录

@foundrykit/advanced-forms-plugin 共发布 33 个版本,首次发布于 2026/05/28;过去 12 个月发布了 33 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
1.16.2latest2026/11/096 天前
1.16.12026/11/096 天前
1.16.02026/11/0610 天前
1.15.12026/11/0610 天前
1.15.02026/11/0610 天前
1.14.12026/10/3116 天前

关于 @foundrykit/advanced-forms-plugin 的常见问题

@foundrykit/advanced-forms-plugin 是什么?

有效载荷 CMS 3 的多步查询表插件

如何安装 @foundrykit/advanced-forms-plugin?

在项目目录运行 npm install @foundrykit/advanced-forms-plugin,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:react(^19)、payload(^3.84.1)、react-hook-form(^7)、@radix-ui/react-popover(^1.1.0)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@foundrykit/advanced-forms-plugin 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@foundrykit/advanced-forms-plugin 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@foundrykit/advanced-forms-plugin 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js ^18.20.2 || >=20.9.0。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@foundrykit/advanced-forms-plugin 可以商用吗?

@foundrykit/advanced-forms-plugin 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@foundrykit/advanced-forms-plugin 的下载量有多少?

根据 npm 官方下载统计,@foundrykit/advanced-forms-plugin 在 2026/10/16 – 2026/11/14 这 30 天内被下载 2,437 次,日均约 81 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@foundrykit/advanced-forms-plugin 还在维护吗?

最新版本 1.16.2 发布于 2026/11/09(6 天前);至今共发布 33 个版本,其中过去 12 个月发布了 33 个;首次发布于 2026/05/28。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。