DocuSeal React 嵌入签署表单:DocusealForm 组件全参数与集成指南
【免费下载链接】docusealOpen source DocuSign alternative. Create, fill, and sign digital documents ✍️项目地址: https://gitcode.com/GitHub_Trending/do/docuseal
本文基于 DocuSeal 官方文档 docs/embedding/signing-form-react.md 整理并深入扩写:以 React 组件DocusealForm为主体,覆盖其完整属性(Attributes)、回调(Callback)与 JWT 鉴权机制,并结合当前开源仓库的路由定义、控制器与配置加载源码,解释src的/d/{slug}与/s/{slug}两类 URL 在服务器端的实际处理链路,帮助你在自有 React 应用中完成嵌入式电子签署流程的落地。
工作原理:两类签署 URL 与后端路由
DocusealForm通过src属性指向 DocuSeal 服务端的表单页面。文档中明确了两类 URL:
/d/{slug}—— 模板级签署表单 URL(template form signing URL)。可在管理后台的模板页面直接复制;模板的slug字段也可以从/templatesAPI 获取。/s/{slug}—— 单个签署人 URL(individual signer URL)。签署人的slug字段可以从/submissionsAPI 获取,适用于通过 API 为带多收件人的模板发起签署请求的场景。
这两类路径与仓库路由定义一一对应,见 config/routes.rb:
resources :start_form, only: %i[show update], path: 'd', param: 'slug' do get :completed end # ... resources :submit_form, only: %i[show update], path: 's', param: 'slug' do resources :values, only: %i[index], controller: 'submit_form_values' # ... end即/d/...由 StartFormController 处理(模板入口,先收集签署人邮箱等信息),/s/...由 SubmitFormController 处理(直接进入具体签署人的签署表单页)。
从 StartFormController#show 的源码结构看,/d/{slug}页面有一个关键前提:模板必须开启了共享链接(@template.shared_link?),否则未登录用户访问会抛出 404;已登录且有权的用户则渲染私有视图。这解释了为什么通过 API 或后台创建模板后,若未配置 sharing,嵌入表单会打不开。
快速开始:最小可运行示例
文档给出的完整示例如下(来自 docs/embedding/signing-form-react.md):
import React from "react" import { DocusealForm } from '@docuseal/react' export function App() { return ( <div className="app"> <DocusealForm src="https://docuseal.com/d/{{template_slug}}" email="{{signer_email}}" onComplete={(data) => console.log(data)} /> </div> ); }其中@docuseal/react是 DocuSeal 提供的 React 封装包(README 中列出的嵌入方案之一,同系列还有 Vue 版 与 Angular 版)。
一个需要在开源仓库语境下说明的重要限制:嵌入式表单组件本身属于 DocuSeal 的付费(Pro)功能。从 EmbedScriptsController 的源码结构看,开源版本在/js/:filename脚本端点(对应 config/routes.rb 中的get '/js/:filename', to: 'embed_scripts#show', as: :embed_script)返回的是一段"占位脚本",它会把自定义元素docuseal-form与docuseal-builder注册为渲染"Upgrade to Pro"升级提示页的占位组件:
const DummyForm = class extends DummyBuilder {}; if (!window.customElements.get('docuseal-form')) { window.customElements.define('docuseal-form', DummyForm); }因此,DocusealForm的完整交互能力(字段渲染、签名画布、完成卡片等)依赖你部署的实例开启了相应许可;本文的参数与回调说明对任何版本的服务端行为仍然成立,可作为集成契约参考。
属性(Attributes)完整参考
以下表格完整继承文档中 JSON 形式的属性定义,并标注了类型、默认值与说明。除src外,其余属性均为可选。
身份与鉴权类
| 属性 | 类型 | 必填 | 说明 |
|---|---|---|---|
src | string | 是 | 签署表单的公开 URL。/d/{slug}为模板表单 URL(可在后台模板页复制,或经/templatesAPI 获取slug);/s/{slug}为单个签署人 URL(经/submissionsAPI 获取) |
email | string | 否 | 签署人邮箱。若不提供,表单会额外显示一个"填写邮箱"的步骤 |
name | string | 否 | 签署人姓名 |
role | string | 否 | 签署人角色或头衔,例如First Party |
token | string | 否 | 用 API key 签名(JWT HS256)的 JSON Web Token。JWT 只能在后端生成,payload 字段见下文 |
externalId | string | 否 | 你的应用中用于唯一标识该签署人的字符串键 |
metadata | object | 否 | 附加签署人信息的元数据对象,示例{ customData: 'custom value' } |
token的 payload 结构(仅可在后端生成):
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
slug | string | 是 | 模板或签署人(Submitter)的 slug。使用 Submitter slug 时无需再传email参数 |
email | string | 否 | 签署人邮箱。配合 Template slug 使用时,若未指定则会出现邮箱填写步骤 |
external_id | string | 否 | 应用内唯一标识签署人的字符串键 |
preview | boolean | 否(默认false) | 以预览模式展示表单,不可提交 |
关于 JWT 在仓库内的实现:开源仓库中提供了通用的 JWT 编解码工具 lib/json_web_token.rb,使用Rails.application.secret_key_base对 payload 进行JWT.encode/JWT.decode。从源码结构看,官方云服务的 token 校验对应"API key 签名"的约定;自托管集成时应以你部署实例实际的校验实现为准,并始终在后端完成 token 生成,前端只负责把结果传给DocusealForm。
展示与交互类
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
expand | boolean | true | 表单打开时是否展开 |
minimize | boolean | false | 设为true时始终最小化表单字段,点击字段才展开 |
orderAsOnPage | boolean | false | 按字段在页面上的位置排序表单字段 |
withTitle | boolean | true | 设为false移除表单中的文档标题 |
withFieldNames | boolean | true | 设为false隐藏字段名(当字段名不是人类可读格式时有用) |
withFieldPlaceholder | boolean | false | 设为true用字段名占位符替代字段类型图标 |
skipFields | boolean | false | 允许跳过表单字段 |
autoscrollFields | boolean | true | 设为false禁用自动滚动到下一个文档字段 |
goToLast | boolean | true | 自动定位到最后一个未完成的步骤 |
onlyRequiredFields | boolean | false | 设为true时分步表单只显示必填字段,隐藏所有可选字段 |
language | string | 浏览器语言 | UI 语言,可用:en, es, it, de, fr, nl, pl, uk, cs, pt, he, ar, kr, ja;默认自动跟随浏览器语言 |
i18n | object | {} | 用于把默认 UI 文案替换为自定义值的键值对象;可用键见 app/javascript/submission_form/i18n.js |
logo | string | 无 | 在签署表单中使用的公开 Logo 图片 URL |
backgroundColor | string | 无 | 表单背景色,仅支持 HEX 颜色码,示例#d9d9d9 |
customCss | string | 无 | 应用于表单的自定义 CSS,示例#submit_form_button { background-color: #d9d9d9; } |
关于i18n:仓库中的文案键集中在 app/javascript/submission_form/i18n.js(约 1600 余行、14 种语言),键名如complete: 'Complete'、sign_and_complete: 'Sign and Complete'、by_clicking_you_agree_to_the: 'By clicking "{button}", you agree to the'(支持{placeholder}插值)、digitally_signed_by: 'Digitally signed by'等。你的i18n对象只需以这些键覆盖对应文案即可。
完成、拒绝与邮件类
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
preview | boolean | false | 预览模式,不可提交。注意:预览模式嵌入已完成文档时要求token鉴权 |
completedRedirectUrl | string | 无 | 提交完成后跳转的 URL,示例https://docuseal.com/success |
completedMessage | object | 无 | 完成后的提示消息,含title(如 "Documents have been signed!")与body(如 "If you have any questions, please contact us.") |
completedButton | object | 无 | 完成后卡片上的自定义按钮,title(按钮文字,如 "Go Back")与url(仅支持绝对 URL,如 "https://example.com")均为必填 |
withDownloadButton | boolean | true | 设为false从完成卡片移除已签署文档下载按钮 |
withSendCopyButton | boolean | true | 设为false从完成卡片移除"发送邮件"按钮 |
withCompleteButton | boolean | false | 设为true在表单头部显示"完成"按钮 |
allowToResubmit | boolean | true | 设为false禁止用户重新提交表单 |
withDecline | boolean | false | 设为true在表单中显示"拒绝"按钮 |
sendCopyEmail | boolean | 默认发送 | 设为false关闭向签署人自动发送已签署文档的邮件(默认会发送) |
这些完成态配置在服务端并非硬编码,而是由账户级配置合并而来。从 lib/submitters/form_configs.rb 可以看到,SubmitFormController渲染表单时会调用Submitters::FormConfigs.call,从account_configs表读取completed_button、completed_message、allow_to_decline、reuse_signature、allow_typed_signature等键值(DEFAULT_KEYS常量)并与前端传入属性共同构成最终表单配置——这解释了为什么completedButton/completedMessage既可以在嵌入属性里覆盖,也可以在后台账户设置中统一配置。
签名与数据预填类
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
allowTypedSignature | boolean | true | 设为false禁止用户输入(打字)签名 |
signature | string | 无 | 预填签名值:可以是 base64 的data:image/字符串、图片的公开 URL,或按标准字体渲染为手写体签名的纯文本 |
rememberSignature | boolean | 无 | 是否记住签名供以后使用;为true时签名存储在签署人浏览器 localStorage 中,之后该签署人的新表单可自动预填 |
reuseSignature | boolean | true | 设为false时不在第二个签名框复用签名,而是重新采集 |
values | object | 无 | 表单字段的预赋值,示例{ 'First Name': 'Jon', 'Last Name': 'Doe' } |
readonlyFields | array | 无 | 只读字段列表,示例['First Name','Last Name'] |
签名预填的服务端对应逻辑在 SubmitFormController#show:当配置允许预填签名(@form_configs[:prefill_signature])时,会优先读取当前用户的已存签名(UserConfigs.load_signature),否则调用Submitters::MaybeAssignDefaultBrowserSignature从浏览器/cookies 中恢复"记住的签名"并挂到@signature_attachment——这正是rememberSignature/signature属性在表单页生效的机制。
回调(Callback)参考
组件提供四个回调属性(均非必填),完整继承文档定义:
| 回调 | 类型 | 触发时机 | 示例 |
|---|---|---|---|
onInit | function | 表单组件初始化时 | () => { console.log("Loaded") } |
onLoad | function | 表单数据加载完成时,接收 data | (data) => { console.log(data) } |
onComplete | function | 表单完成提交后,接收 data | (data) => { console.log(data) } |
onDecline | function | 表单被拒绝后,接收 data(配合withDecline) | (data) => { console.log(data) } |
一个贴近实际业务的组合示例(在文档最小示例基础上扩展常用属性):
<DocusealForm src={`https://your-docuseal-instance.com/d/${templateSlug}`} email={signerEmail} name={signerName} role="First Party" token={jwtFromBackend} // 后端生成的 JWT logo="https://your-cdn.com/logo.png" language="en" completedRedirectUrl="https://example.com/success" completedButton={{ title: "Go Back", url: "https://example.com" }} withDecline onComplete={(data) => trackEvent('form_completed', data)} onDecline={(data) => trackEvent('form_declined', data)} />源码级流程解析:一次嵌入签署如何走完后端
结合仓库源码,可以把嵌入表单的完整链路拆成三段,便于排查集成问题:
1. 入口页(/d/{slug})
StartFormController 是/d路由的处理器:
show动作校验模板为共享链接(shared_link?),并处理require_phone_2fa/require_email_2fa等偏好——开启手机/邮箱两步验证的模板会直接对匿名嵌入访问抛出 404(见 app/controllers/start_form_controller.rb)。update动作执行find_or_initialize_submitter:按link_form_fields(默认['email'])在模板的非过期、未拒绝 Submission 中find_or_initialize_by现有签署人,找不到则创建新 Submission(source: :link)与 Submitter,随后redirect_to submit_form_path(@submitter.slug)跳转到/s/{submitter_slug}。- 若模板定义了多个"未指定收件人"且传入的是新记录,会渲染
multiple_submitters_error_message错误——这是多签署人模板使用共享链接时的典型报错场景。
2. 签署页(/s/{slug})
SubmitFormController 负责字段填写与提交:
show在渲染前经过maybe_render_locked_page(模板/Submission 已归档、已过期或已拒绝时渲染对应锁定页)、maybe_require_link_2fa(共享链接两步验证未通过则重定向回/d入口)等前置动作。update先调用Submitters::AuthorizedForForm.call做鉴权(其实现见 lib/submitters/authorized_for_form.rb,分别校验pass_email_2fa?与pass_link_2fa?,支持加密 cookieemail_2fa_slug或two_factor_token参数/请求头),随后调用Submitters::SubmitValues.call保存字段值;必填字段缺失时返回422 + { field_uuid },验证失败返回422 + { error }。
3. 完成与事件
完成卡片的行为(下载按钮、发送邮件按钮、完成按钮文案)由前文所述的FormConfigs决定;preview属性对应的是/e/{slug}预览路由(config/routes.rb 中的submissions_preview),文档特别指出预览模式嵌入已完成文档需要token鉴权。
集成注意事项与边界条件
email与token的关系:不传email(且 token payload 中也没有email,且用的是 Template slug)时,表单会多出邮箱填写步骤;用 Submitter slug 时则无需再传 email。- 多签署人模板:
/d/{slug}共享链接方式要求模板中的签署人可被唯一确定(filter_undefined_submitters相关逻辑);多人签署建议走/s/{submitter_slug}或 JWT + Submitter slug。 - 重提交(
allowToResubmit):从 StartFormController#can_resubmit? 看,重提交还受服务端约束:原签署需已完成、完成时间在 14 天内、来源非api/embed/mcp,且账户配置允许——即前端传allowToResubmit={false}是"只能更严",服务端规则是最终边界。 - 语言列表:文档列出的 14 种语言(
en, es, it, de, fr, nl, pl, uk, cs, pt, he, ar, kr, ja)与 app/javascript/submission_form/i18n.js 中维护的语言文案一致;kr为文档原样写法。 - 预览模式:
preview只读展示;若要在预览中查看已完成的文档,必须提供token。 completedButton.url仅接受绝对 URL,backgroundColor仅接受 HEX 色值,customCss用于细粒度覆盖(如按钮颜色)。
延伸阅读
- 其他框架的嵌入文档:JavaScript 版、Vue 版、Angular 版、表单构建器 React 版
- API 文档:docs/api/ruby.md(含
/templates、/submissions端点说明,用于获取 slug) - Webhook 事件参考:docs/webhooks/submission-webhook.md
- 服务端关键实现:StartFormController、SubmitFormController、FormConfigs、AuthorizedForForm、JsonWebToken
【免费下载链接】docusealOpen source DocuSign alternative. Create, fill, and sign digital documents ✍️项目地址: https://gitcode.com/GitHub_Trending/do/docuseal
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考