kibbleforms

中文文档
0.1.5发布于 2026/11/04MITTypeScriptESM + CJS

编码代理构建的站点的表单。React组件、客户端SDK和 kibble CLI。

中文使用文档
文档目录9 节
  1. 60秒快速入门(也适用于代理商)
  2. 条件逻辑,预填充,自动完成,调度
  3. 代理
  4. CSS设置
  5. 定制
  6. 组件
  7. 客户端SDK
  8. CLI
  9. 文档

kibbleforms

编码代理构建的站点的入站表单。表单存在于你的代码中; 粗磨 处理提交后的所有事情:验证、垃圾邮件保护、随表单变化保持一致的存储、部分提交以及发送到电子邮件和webhook。

一个包裹,三样东西:

  • 反应组件 那一副从盒子里拿出来的样子kibbleforms)在…之上 无头原语 (kibbleforms/headless)
  • 一个 客户端SDK (kibbleforms/client)与幂等,重试提交
  • 这个 kibble CLI (npx kibble …),用于配置、推送模式、测试和检查构建
npm install kibbleforms

反应18或19。工作在Next.js(应用路由器),Vite, Astro + React, Remix。文档: kibbleforms.com/docs ·每个版本都有哪些变化: 更新日志。

60秒快速入门(也适用于代理商)

npx kibble init            # sandbox project; writes kibble.json, .kibble/secret, kibble/client.ts, an AGENTS.md section,
                           # adds withKibble()/kibble() to your next/vite/astro config and the CSS imports, prints a claim link
// kibble/forms/waitlist.ts
import { defineForm } from 'kibbleforms/schema';

export const waitlist = defineForm({
  slug: 'waitlist',
  name: 'Waitlist',
  pages: [
    {
      fields: [
        { key: 'email', type: 'email', label: 'Work email', required: true },
        { key: 'name', type: 'short_text', label: 'Name' },
        { key: 'role', type: 'dropdown', label: 'Role', options: ['Founder', 'Engineer', 'Other'] },
        { key: 'consent', type: 'consent', label: 'Email me when we launch', required: true },
      ],
    },
  ],
  settings: {
    submitLabel: 'Join the waitlist',
    success: { type: 'message', title: 'You are on the list', message: 'We will be in touch.' },
  },
});
// anywhere in your site
import { Form } from 'kibbleforms';
import { kibble } from '@/kibble/client';
import { waitlist } from '@/kibble/forms/waitlist';

export function Waitlist() {
  return <Form schema={waitlist} client={kibble} />;
}
npm run dev                # the plugin registers a form whenever its file is saved
npx kibble test waitlist   # send a test submission from localhost and confirm it landed

没有需要记住的推进步骤: withKibble(nextConfig) (kibbleforms/next)或 kibble() (kibbleforms/vite(也包括Astro和React Router)从开发服务器注册表单并运行 kibble sync 在构建。项目认领后, npx kibble env vercel (或 netlify, print)为部署构建提供键,以便它们也注册它们的表单;没有它,只有当访问者被拒绝时,构建才会失败。

这是一个本地主机上的工作表单,没有人工步骤。要上线,一个人打开索赔链接(npx kibble claim --open),登录并命名生产域。在此之前,该项目是一个 沙盒:它只接受来自本地主机的提交,其数据在72小时后过期。

字段类型: short_text, long_text, email, phone, url, number, single_choice, multiple_choice, dropdown, yes_no, rating, date, consent, hidden. 多于一页的表单是多步骤表单;每一步之后都会保存进度。

条件逻辑,预填充,自动完成,调度

  • 条件字段和页面: showWhen: { field: 'role', op: 'eq', value: 'other' } (或 { all: [...] } / { any: [...] })在一个领域或一页。隐藏字段不被验证,不是必需的,永远不会发送;没有可见字段的页面将被跳过并 Progress 只计算可见页面。钩子暴露了 visibleKeys, visiblePages, isFieldVisible(key), isPageVisible(i)。
  • 预先填充: prefill: { query: 'email' } 在挂载时填充URL查询中的字段(隐藏字段默认为自己的键); initialValues 在 Form/useKibbleForm 是程序化的预填充和获胜。
  • 自动完成: autocomplete: 'name' | 'given-name' | 'organization' | … 成为HTML属性(email/tel/url字段得到合理的默认值)。
  • 调度: success: { type: 'schedule', url: 'https://calendly.com/acme/demo' } 重定向, name 和 email 肾上腺素和 utm_* 通过; redirect 接受 prefill 了。钩子暴露了 successUrl 和 resolveSuccessUrl() 用于自定义ui,以及 navigate 让你替换 window.location.assign。

代理

表格可以由代理填写。 settings.agents 是 'accept' (默认;已声明的代理被标记)或 'block', settings.agentNotes 描述好的答案;代理读 GET /v1/projects/<projectId>/forms/<slug>/schema.json 然后提交 meta.actor: { type: 'agent', name }. 在SDK中: createClient({ actor }) 或 useKibbleForm(schema, { actor }). 一个 block 政策的回报 agents_blocked;的风格 Form 显示服务器的消息和提示。

CSS设置

组件是用Tailwind v4实用程序编写的,该实用程序读取 --kb-* CSS变量。选择一个:

顺风v4主机 你的CSS文件; kibble init 添加):

@import "tailwindcss";
@import "kibbleforms/theme.css";                 /* --kb-* tokens + @theme mapping (bg-kb-primary, rounded-kb, …) */
@import "kibbleforms/themes/shadcn.css";         /* shadcn/ui sites: use your --primary, --radius, … (v3: shadcn-v3.css) */
@source "../node_modules/kibbleforms/dist";      /* let Tailwind see the component classes; adjust the relative path */

该表单继承您的字体并跟随 .dark / [data-theme="dark"] 祖先。使用道具进行调整: theme (颜色, radius, font, colorScheme), size (sm | md | lg), layout ({ columns: 2 }), classNames (按部分上课),上 Form 或者曾经 KibbleProvider。

没有顺风 (任何捆绑者,或一个 <link>):

import 'kibbleforms/styles.css';   // compiled and scoped to [data-kibble]; nothing leaks into your page

定制

  1. CSS变量 -两种分布都一样。全局或每个表单设置它们:

    :root { --kb-primary: #2563eb; --kb-radius: 999px; --kb-font: var(--font-sans); }
    [data-kibble] { --kb-space: 1rem; }
    

    令牌: --kb-primary, --kb-primary-fg, --kb-bg, --kb-fg, --kb-muted, --kb-muted-fg, --kb-border, --kb-ring, --kb-error, --kb-radius, --kb-space, --kb-font. 每个组件也呈现 data-kb="<name>" (form, field, label, input, select, choice, option, yesno, rating, date, consent, submit, error, success, multistep, progress, nav, notice, page, help)用于纯CSS定位。

  2. 组合和覆盖类 -每个组件 className与…合并 tailwind-merge 所以你的公用事业赢了:

    <Form schema={waitlist} client={kibble} className="grid grid-cols-2 gap-4">
      <Field name="name" />
      <Field name="email" />
      <Field name="role" className="col-span-2" />
      <Field name="consent" className="col-span-2" />
      <Submit className="col-span-2 w-auto justify-self-end">Count me in</Submit>
    </Form>
    
  3. 无头 -行为和可访问性,零标记意见;

    import { useKibbleForm, FormProvider, useField, Honeypot } from 'kibbleforms/headless';
    
    function Email() {
      const { field, value, setValue, error, inputProps, errorId } = useField('email');
      return (
        <label>
          {field.label}
          <input {...inputProps} value={(value as string) ?? ''} onChange={(e) => setValue(e.target.value)} />
          {error && <p id={errorId}>{error}</p>}
        </label>
      );
    }
    
    export function Custom() {
      const form = useKibbleForm(waitlist, { client: kibble });
      return (
        <FormProvider form={form}>
          <form {...form.formProps}>
            <Honeypot />
            <Email />
            <button type="submit" disabled={form.status === 'submitting'}>Send</button>
          </form>
        </FormProvider>
      );
    }
    

    useKibbleForm 给你 values, errors, touched, pageIndex, pageCount, status, result, submitError, setValue, setTouched, validatePage, nextPage, prevPage, submit, reset, formProps 和更多。 useField 返回 inputProps 与 id, name, aria-invalid, aria-describedby, aria-required 和 onBlur (我们使用 aria-required 而不是 required 所以显示的是我们的消息,而不是浏览器的)。 usePage() 和 useFormStatus() 覆盖导航和状态。

组件

Form (在没有子项的情况下,从图式呈现整个形式; MultiStep 当有超过一页时自动), KibbleProvider, Page, MultiStep, Progress, Field (按类型选择控件), Input, Textarea, Select, Choice (单选或复选框组), YesNo, Rating, DatePicker, Consent, Submit, FieldError, Success, Label, Help, Button。

您可以免费获得的行为:提交时的模式验证(模糊时的格式错误,“required”等待提交),焦点移动到第一个无效控件或新页面的标题,Enter提交单页表单并推进多步骤表单,蜜罐字段,提交时间,访问者来自何处(导致表单的页面,登录页面,入口站点和活动标签;添加 <KibbleAttribution /> 到根布局以覆盖表单之前的页面),可选的Cloudflare Turnstile (settings.turnstileSiteKey),幂等提交,在网络上重试3次/5xx错误,在会话id下保存的每一步部分 sessionStorage,以及成功消息或重定向从 settings.success (服务器的echo获胜)。

使用 <KibbleProvider client={kibble}> 一次(例如在Next.js布局中通过一个小的客户端组件),以便页面可以渲染 <Form schema={…} /> 不通过客户端。在服务器组件框架中,从 kibbleforms/schema 还有来自 kibbleforms/client;默认条目是客户端代码。

客户端SDK

import { createClient, KibbleError } from 'kibbleforms/client';

const kibble = createClient({ projectId: 'prj_…', endpoint: 'https://api.kibbleforms.com' });
const res = await kibble.submit(waitlist, { email: '[email protected]', consent: true }, { startedAt });
// res: { id, status, success?, flags? }  — throws KibbleError { code, message, hint, fields, status }
await kibble.savePartial(waitlist, values, { sessionId, pageIndex: 0 }); // never throws, null on failure

服务器总是根据注册的模式版本进行验证;客户机验证是一种便利。提交的文件带有 Idempotency-Key (每个逻辑提交一个,跨重试重用)和模式哈希,以便Kibble知道它们属于哪个版本。

CLI

每个命令都接受 --json (标准输出上的机器可读输出,没有其他)。退出代码: 0 好吧, 1 错误, 2 检查失败。错误总是告诉我们下一步该怎么做。

命令它是做什么的
kibble init [--name] [--api-url] [--forms-dir kibble/forms] [--force]创建沙盒项目。写 kibble.json, .kibble/secret (gitignored), kibble/client.ts、forms目录和 ## Kibble forms 部分 AGENTS.md/CLAUDE.md. 打印索赔链接。
kibble push [slug]注册forms目录中的每个模式(加载了jiti、TypeScript就可以了)。打印版本、diff和警告。框架插件使得很少需要这样做。
kibble sync构建步骤:使用 KIBBLE_SECRET_KEY (或 .kibble/secret)注册每个表单标记其来源(Vercel, netflix, Cloudflare Pages, GitHub Actions, KIBBLE_ENV); 没有它,只有在访客被拒绝时才会检查和离开。
kibble env vercel|netlify|print将密钥放入主机的构建环境中(Vercel的标准输入,不回显),或者打印密钥以进行粘贴。
kibble test [slug]从localhost发送带有样例值的测试提交,并确认它已被存储。
kibble status模式、声明状态、起源和具有本地vs远程模式漂移的表单表。
kibble check [--allow-sandbox]严格本地检查:如果项目未被认领或本地模式未注册,则退出2。
kibble claim [--open] [--wait]打印(并打开)索赔链接; --wait 投票直到项目上线。
kibble submissions [slug] [--status all|complete|partial|spam|test] [--limit 20]列出最近的回复,包括类型、日期和第一次回复。
kibble destinations list / add slack (为某人打印“添加到Slack”链接)或 add slack <url> / add postgres "<conn>" [--table t] [--schema s] / add email <member addr> / add webhook <url> (每 --form slug 或 --all-forms) / remove <id> / test <id>连接Slack, Postgres(包括Supabase pooler),向工作区成员发送电子邮件和签名webhook,而不需要仪表板。连接字符串永远不会回显;Webhook签名秘密打印一次。
kibble domains list|add <domain>|remove <domain>站点的生产域(允许的来源)。
kibble review <slug> [--ideal "…"] [--categories "A,B"] [--off|--on]显示或更改表单的分类(理想响应支持适合级别)。

配置: kibble.json ({ projectId, apiUrl, formsDir }),秘密地 .kibble/secret (KIBBLE_SECRET_KEY 覆盖(在CI中很有用); KIBBLE_API_URL 为设置默认API init。

文档

https://api.kibbleforms.com/llms.txt 和 /docs/*.md 都是为特工和人类写的。

麻省理工学院

版本与发布记录

kibbleforms 共发布 7 个版本,首次发布于 2026/10/27;过去 12 个月发布了 7 个版本。

版本发布日期距今
0.1.5latest2026/11/041 天前
0.1.42026/10/288 天前
0.1.32026/10/278 天前
0.1.22026/10/279 天前
0.1.12026/10/279 天前
0.1.02026/10/279 天前

关于 kibbleforms 的常见问题

kibbleforms 是什么?

编码代理构建的站点的表单。React组件、客户端SDK和 kibble CLI。

如何安装 kibbleforms?

在项目目录运行 npm install kibbleforms,或使用 pnpm add / yarn add / bun add。它还提供命令行工具 kibble,可以用 npx kibble 直接运行。

kibbleforms 支持 TypeScript 吗?

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

kibbleforms 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

kibbleforms 可以商用吗?

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

kibbleforms 还在维护吗?

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