feat: docs v2 (#2460)

Co-authored-by: Catalin Pit <catalinpit@gmail.com>
This commit is contained in:
Lucas Smith
2026-02-27 22:05:27 +11:00
committed by GitHub
parent f8ac782f2e
commit b92c53dbb2
290 changed files with 32521 additions and 266 deletions
@@ -0,0 +1,306 @@
---
title: Authoring
description: Embed document and template creation directly in your application.
---
import { Callout } from 'fumadocs-ui/components/callout';
In addition to embedding signing, Documenso supports embedded authoring. It allows your users to create and edit documents and templates without leaving your application.
<Callout type="warn">
Embedded authoring is included with [Enterprise](https://documen.so/enterprise-cta) plans. It is
also available as a paid add-on for the [Platform Plan](https://documen.so/platform-cta-pricing).
Contact sales for access.
</Callout>
## Components
The SDK provides four authoring components:
| Component | Purpose |
| ----------------------- | ----------------------- |
| `EmbedCreateDocumentV1` | Create new documents |
| `EmbedCreateTemplateV1` | Create new templates |
| `EmbedUpdateDocumentV1` | Edit existing documents |
| `EmbedUpdateTemplateV1` | Edit existing templates |
All authoring components require a **presign token** for authentication instead of a regular token.
---
## Presign Tokens
Before using any authoring component, obtain a presign token from your backend:
```
POST /api/v2/embedding/create-presign-token
```
This endpoint requires your Documenso API key. The token has a default expiration of 1 hour.
See the [API documentation](https://openapi.documenso.com/reference#tag/embedding) for full details.
<Callout type="warn">
Presign tokens should be created server-side. Never expose your API key in client-side code.
</Callout>
---
## Creating Documents
```jsx
import { EmbedCreateDocumentV1 } from '@documenso/embed-react';
const DocumentCreator = ({ presignToken }) => {
return (
<div style={{ height: '800px', width: '100%' }}>
<EmbedCreateDocumentV1
presignToken={presignToken}
externalId="order-12345"
onDocumentCreated={(data) => {
console.log('Document created:', data.documentId);
console.log('External ID:', data.externalId);
}}
/>
</div>
);
};
```
---
## Creating Templates
```jsx
import { EmbedCreateTemplateV1 } from '@documenso/embed-react';
const TemplateCreator = ({ presignToken }) => {
return (
<div style={{ height: '800px', width: '100%' }}>
<EmbedCreateTemplateV1
presignToken={presignToken}
externalId="template-12345"
onTemplateCreated={(data) => {
console.log('Template created:', data.templateId);
}}
/>
</div>
);
};
```
---
## Editing Documents
```jsx
import { EmbedUpdateDocumentV1 } from '@documenso/embed-react';
const DocumentEditor = ({ presignToken, documentId }) => {
return (
<div style={{ height: '800px', width: '100%' }}>
<EmbedUpdateDocumentV1
presignToken={presignToken}
documentId={documentId}
externalId="order-12345"
onDocumentUpdated={(data) => {
console.log('Document updated:', data.documentId);
}}
/>
</div>
);
};
```
---
## Editing Templates
```jsx
import { EmbedUpdateTemplateV1 } from '@documenso/embed-react';
const TemplateEditor = ({ presignToken, templateId }) => {
return (
<div style={{ height: '800px', width: '100%' }}>
<EmbedUpdateTemplateV1
presignToken={presignToken}
templateId={templateId}
externalId="template-12345"
onTemplateUpdated={(data) => {
console.log('Template updated:', data.templateId);
}}
/>
</div>
);
};
```
---
## Props
### All Authoring Components
| Prop | Type | Required | Description |
| ------------------ | --------- | -------- | -------------------------------------------------------- |
| `presignToken` | `string` | Yes | Authentication token from your backend |
| `externalId` | `string` | No | Your reference ID to link with the document or template |
| `host` | `string` | No | Custom host URL. Defaults to `https://app.documenso.com` |
| `css` | `string` | No | Custom CSS string (Platform Plan) |
| `cssVars` | `object` | No | CSS variable overrides (Platform Plan) |
| `darkModeDisabled` | `boolean` | No | Disable dark mode (Platform Plan) |
| `className` | `string` | No | CSS class for the iframe |
| `features` | `object` | No | Feature toggles for the authoring experience |
### Update Components Only
| Prop | Type | Required | Description |
| ---------------- | --------- | -------- | ---------------------------------------------------------- |
| `documentId` | `number` | Yes | The document ID to edit (for document update component) |
| `templateId` | `number` | Yes | The template ID to edit (for template update component) |
| `onlyEditFields` | `boolean` | No | Restrict editing to fields only, skipping recipient config |
---
## Feature Toggles
Customize what options are available in the authoring experience:
```jsx
<EmbedCreateDocumentV1
presignToken={presignToken}
features={{
allowConfigureSignatureTypes: true,
allowConfigureLanguage: true,
allowConfigureDateFormat: true,
allowConfigureTimezone: true,
allowConfigureRedirectUrl: true,
allowConfigureCommunication: true,
}}
/>
```
---
## Event Callbacks
All creation callbacks receive:
| Field | Type | Description |
| ---------------------------- | -------- | --------------------------------------- |
| `documentId` or `templateId` | `number` | The ID of the created or updated item |
| `externalId` | `string` | Your external reference ID, if provided |
---
## Field-Only Editing
Restrict users to editing fields only, skipping recipient configuration:
```jsx
<EmbedUpdateDocumentV1
presignToken={presignToken}
documentId={123}
onlyEditFields={true}
onDocumentUpdated={(data) => {
console.log('Fields updated:', data.documentId);
}}
/>
```
---
## Complete Integration Example
This example shows a full workflow where users create a document and then edit it:
```tsx
import { useState } from 'react';
import { EmbedCreateDocumentV1, EmbedUpdateDocumentV1 } from '@documenso/embed-react';
const DocumentManager = ({ presignToken }) => {
const [documentId, setDocumentId] = useState(null);
const [mode, setMode] = useState('create');
if (mode === 'success') {
return (
<div>
<h2>Document updated successfully</h2>
<button
onClick={() => {
setDocumentId(null);
setMode('create');
}}
>
Create Another Document
</button>
</div>
);
}
if (mode === 'edit' && documentId) {
return (
<div style={{ height: '800px', width: '100%' }}>
<button onClick={() => setMode('create')}>Back to Create</button>
<EmbedUpdateDocumentV1
presignToken={presignToken}
documentId={documentId}
onDocumentUpdated={(data) => {
console.log('Document updated:', data.documentId);
setMode('success');
}}
/>
</div>
);
}
return (
<div style={{ height: '800px', width: '100%' }}>
<EmbedCreateDocumentV1
presignToken={presignToken}
features={{
allowConfigureSignatureTypes: true,
allowConfigureLanguage: true,
}}
onDocumentCreated={(data) => {
console.log('Document created:', data.documentId);
setDocumentId(data.documentId);
setMode('edit');
}}
/>
</div>
);
};
```
---
## Additional Props
Pass extra props to the iframe for testing experimental features:
```jsx
<EmbedCreateDocumentV1
presignToken="YOUR_PRESIGN_TOKEN"
additionalProps={{
experimentalFeature: true,
customSetting: 'value',
}}
/>
```
<Callout type="info">
Presign tokens expire after 1 hour by default. You can customize this duration based on your
security requirements. Generate fresh tokens for each session and avoid caching them on the client
side.
</Callout>
---
## See Also
- [Embedding Overview](/docs/developers/embedding) - Signing embed concepts and props
- [CSS Variables](/docs/developers/embedding/css-variables) - Customize appearance
- [Documents API](/docs/developers/api/documents) - Create documents via API
- [Templates API](/docs/developers/api/templates) - Create templates via API
@@ -0,0 +1,215 @@
---
title: CSS Variables
description: Customize the appearance of embedded signing experiences with CSS variables and class targets.
---
import { Accordion, Accordions } from 'fumadocs-ui/components/accordion';
import { Callout } from 'fumadocs-ui/components/callout';
<Callout type="info">
Custom CSS and CSS variables are available on the [Platform
Plan](https://documen.so/platform-cta-pricing).
</Callout>
## CSS Variables
Use the `cssVars` prop on any embed component to override default colors, spacing, and more.
```jsx
<EmbedDirectTemplate
token="your-token"
cssVars={{
background: '#ffffff',
foreground: '#000000',
primary: '#0000ff',
primaryForeground: '#ffffff',
radius: '0.5rem',
}}
/>
```
### Colors
| Variable | Description |
| ----------------------- | --------------------------------- |
| `background` | Base background color |
| `foreground` | Base text color |
| `muted` | Muted/subtle background color |
| `mutedForeground` | Muted/subtle text color |
| `popover` | Popover/dropdown background color |
| `popoverForeground` | Popover/dropdown text color |
| `card` | Card background color |
| `cardBorder` | Card border color |
| `cardBorderTint` | Card border tint/highlight color |
| `cardForeground` | Card text color |
| `fieldCard` | Field card background color |
| `fieldCardBorder` | Field card border color |
| `fieldCardForeground` | Field card text color |
| `widget` | Widget background color |
| `widgetForeground` | Widget text color |
| `border` | Default border color |
| `input` | Input field border color |
| `primary` | Primary action/button color |
| `primaryForeground` | Primary action/button text color |
| `secondary` | Secondary action/button color |
| `secondaryForeground` | Secondary button text color |
| `accent` | Accent/highlight color |
| `accentForeground` | Accent/highlight text color |
| `destructive` | Destructive/danger action color |
| `destructiveForeground` | Destructive/danger text color |
| `ring` | Focus ring color |
| `warning` | Warning/alert color |
### Spacing
| Variable | Description |
| -------- | ---------------------------------- |
| `radius` | Border radius size (e.g. `0.5rem`) |
### Framework Usage
Pass `cssVars` to any embed component. The syntax varies by framework:
```jsx
// React / Preact
<EmbedDirectTemplate token={token} cssVars={cssVars} />
// Vue
<EmbedDirectTemplate :token="token" :cssVars="cssVars" />
// Svelte
<EmbedDirectTemplate {token} cssVars={cssVars} />
// Solid
<EmbedDirectTemplate token={token} cssVars={cssVars} />
```
### Color Formats
Colors can be specified in any valid CSS format:
- Hex: `#ff0000`
- RGB: `rgb(255, 0, 0)`
- HSL: `hsl(0, 100%, 50%)`
- Named: `red`
---
## Custom CSS
Use the `css` prop to inject a CSS string for more targeted control:
```jsx
<EmbedDirectTemplate
token="your-token"
css={`
.documenso-embed {
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
`}
/>
```
---
## CSS Class Targets
Specific parts of the embed can be targeted with CSS classes for granular styling.
### Component Classes
| Class | Description |
| --------------------------------- | --------------------------------------------- |
| `.embed--Root` | Main container for the embedded experience |
| `.embed--DocumentContainer` | Container for the document and signing widget |
| `.embed--DocumentViewer` | Container for the document viewer |
| `.embed--DocumentWidget` | The signing widget container |
| `.embed--DocumentWidgetContainer` | Outer container for the signing widget |
| `.embed--DocumentWidgetHeader` | Header section of the signing widget |
| `.embed--DocumentWidgetContent` | Main content area of the signing widget |
| `.embed--DocumentWidgetForm` | Form section within the signing widget |
| `.embed--DocumentWidgetFooter` | Footer section of the signing widget |
| `.embed--WaitingForTurn` | Waiting screen when it is not the user's turn |
| `.embed--DocumentCompleted` | Completion screen after signing |
| `.field--FieldRootContainer` | Base container for document fields |
### Field Data Attributes
Fields expose data attributes for state-based styling:
| Attribute | Values | Description |
| ------------------- | ---------------------------------------------- | ------------------------------------ |
| `[data-field-type]` | `SIGNATURE`, `TEXT`, `CHECKBOX`, `RADIO`, etc. | The type of field |
| `[data-inserted]` | `true`, `false` | Whether the field has been filled |
| `[data-validate]` | `true`, `false` | Whether the field is being validated |
### Example
```css
/* Style signature fields */
.field--FieldRootContainer[data-field-type='SIGNATURE'] {
background-color: rgba(0, 0, 0, 0.02);
}
/* Style filled fields */
.field--FieldRootContainer[data-inserted='true'] {
background-color: var(--primary);
opacity: 0.2;
}
/* Custom widget styling */
.embed--DocumentWidget {
background-color: #ffffff;
box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1);
}
```
### Additional Examples
```css
/* Style all field containers with transitions */
.field--FieldRootContainer {
transition: all 200ms ease;
}
/* Custom styles for the waiting screen */
.embed--WaitingForTurn {
background-color: #f9fafb;
padding: 2rem;
}
/* Responsive adjustments for the document container */
@media (min-width: 768px) {
.embed--DocumentContainer {
gap: 2rem;
}
}
```
---
## Best Practices
<Accordions type="multiple">
<Accordion title="Maintain contrast">
Ensure sufficient contrast between background and foreground colors for accessibility.
</Accordion>
<Accordion title="Test dark mode">
If dark mode is not disabled, verify your variables work in both modes.
</Accordion>
<Accordion title="Match your brand">
Align `primary` and `accent` colors with your brand for a cohesive look.
</Accordion>
<Accordion title="Consistent radius">
Use a border radius that matches your application's design system.
</Accordion>
</Accordions>
---
## See Also
- [Embedding Overview](/docs/developers/embedding) - Props reference and concepts
- [React](/docs/developers/embedding/sdks/react) - React SDK usage
- [Vue](/docs/developers/embedding/sdks/vue) - Vue SDK usage
@@ -0,0 +1,514 @@
---
title: Direct Links
description: Share a URL or embed an iframe to let users sign documents without email invitations.
---
import { Callout } from 'fumadocs-ui/components/callout';
import { Step, Steps } from 'fumadocs-ui/components/steps';
import { Tab, Tabs } from 'fumadocs-ui/components/tabs';
## What Are Direct Links?
Direct links are unique URLs tied to a template that allow anyone to:
{/* prettier-ignore */}
<Steps>
<Step>
View and sign a document without receiving an email invitation
</Step>
<Step>
Enter their own name and email address
</Step>
<Step>
Complete signature fields and submit the document
</Step>
</Steps>
When someone uses a direct link, Documenso creates a new document from the template with that person as the signer.
### When to Use Direct Links
- Collecting signatures from unknown recipients (forms, waivers, petitions)
- Embedding signing in your website or application
- Self-service contracts where customers initiate signing
- Public-facing agreements that anyone can sign
### Limitations
- Only work with templates, not individual documents
- Each link is tied to one recipient role in the template
- Recipients enter their own information (you cannot prefill recipient details)
## Creating Direct Link Templates
Before embedding, you need a template with direct links enabled.
### Via the Dashboard
{/* prettier-ignore */}
<Steps>
<Step>
Go to **Templates** and create or select a template
![Team templates](/embedding/team-templates.png)
</Step>
<Step>
Click the three-dot menu and select **Direct link**
</Step>
<Step>
Click **Enable direct link signing**
</Step>
<Step>
Choose which recipient in your template will use the direct link
![Enable direct link](/embedding/enable-direct-link.png)
</Step>
<Step>
Copy the generated URL
</Step>
</Steps>
### Via the API
Create a direct link for an existing template:
<Tabs items={['curl', 'TypeScript']}>
<Tab value="curl">
```bash
# Create direct link for template
curl -X POST "https://app.documenso.com/api/v2/template/direct/create" \
-H "Authorization: api_xxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"templateId": 123,
"directRecipientId": 1
}'
```
</Tab>
<Tab value="TypeScript">
```typescript
const API_TOKEN = process.env.DOCUMENSO_API_TOKEN;
const BASE_URL = 'https://app.documenso.com/api/v2';
const response = await fetch(`${BASE_URL}/template/direct/create`, {
method: 'POST',
headers: {
Authorization: API_TOKEN,
'Content-Type': 'application/json',
},
body: JSON.stringify({
templateId: 123,
directRecipientId: 1, // Optional: specific recipient to use
}),
});
const directLink = await response.json();
console.log('Direct link token:', directLink.token);
// URL: https://app.documenso.com/d/{token}
````
</Tab>
</Tabs>
### Response
```json
{
"id": 456,
"token": "abc123xyz",
"templateId": 123,
"directTemplateRecipientId": 1,
"enabled": true,
"createdAt": "2025-01-15T10:00:00.000Z"
}
````
The direct link URL format is:
```
https://app.documenso.com/d/{token}
```
![Copy recipient token](/embedding/copy-recipient-token.png)
---
## Embedding in an iframe
Embed the signing experience directly in your application using an iframe.
### Basic iframe Embedding
```html
<iframe
src="https://app.documenso.com/embed/direct/abc123xyz"
width="100%"
height="800"
frameborder="0"
allow="clipboard-write"
></iframe>
```
### Responsive iframe
```html
<div style="position: relative; width: 100%; padding-bottom: 75%; height: 0; overflow: hidden;">
<iframe
src="https://app.documenso.com/embed/direct/abc123xyz"
style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border: none;"
allow="clipboard-write"
></iframe>
</div>
```
### React Component Example
```tsx
function DocumentSigner({ token }: { token: string }) {
return (
<div className="h-[800px] w-full">
<iframe
src={`https://app.documenso.com/embed/direct/${token}`}
className="h-full w-full border-0"
allow="clipboard-write"
title="Sign Document"
/>
</div>
);
}
```
<Callout type="info">
The embed URL uses `/embed/direct/{token}` instead of `/d/{token}`. The embed version is optimized
for iframe embedding with reduced navigation.
</Callout>
---
## Embedding with Redirect
Instead of an iframe, redirect users to the signing page and bring them back after completion.
### Simple Redirect
```typescript
function redirectToSigning(token: string) {
window.location.href = `https://app.documenso.com/d/${token}`;
}
```
### With Return URL
Configure a redirect URL in your template settings to return users to your application after signing:
{/* prettier-ignore */}
<Steps>
<Step>
Edit your template
</Step>
<Step>
Go to **Advanced Settings**
</Step>
<Step>
Set **Redirect URL** to your desired return URL (e.g., `https://yourapp.com/signed`)
</Step>
</Steps>
Or set it via API when creating the template:
```typescript
const response = await fetch(`${BASE_URL}/template/update`, {
method: 'POST',
headers: {
Authorization: API_TOKEN,
'Content-Type': 'application/json',
},
body: JSON.stringify({
templateId: 123,
meta: {
redirectUrl: 'https://yourapp.com/signing-complete',
},
}),
});
```
After signing completes, users are automatically redirected to the specified URL.
---
## URL Parameters
Pass additional data through the direct link URL using query parameters.
### External ID
Track which document belongs to which transaction in your system:
```
https://app.documenso.com/d/abc123xyz?externalId=order-12345
```
The external ID is stored with the created document and included in webhook payloads.
### Example: Dynamic External ID
```typescript
function getSigningUrl(token: string, orderId: string) {
const params = new URLSearchParams({
externalId: orderId,
});
return `https://app.documenso.com/d/${token}?${params.toString()}`;
}
// Usage
const url = getSigningUrl('abc123xyz', 'order-12345');
// https://app.documenso.com/d/abc123xyz?externalId=order-12345
```
### Embed URL Parameters
The embed URL supports the same parameters:
```
https://app.documenso.com/embed/direct/abc123xyz?externalId=order-12345
```
---
## Security Considerations
### Access Authentication
Direct links can require authentication before signing. Configure this in your template settings:
| Auth Type | Description |
| --------- | ---------------------------------------------- |
| None | Anyone with the link can sign |
| Account | Signer must be logged into a Documenso account |
To require authentication, set `globalAccessAuth` when creating or updating the template:
```typescript
const response = await fetch(`${BASE_URL}/template/update`, {
method: 'POST',
headers: {
Authorization: API_TOKEN,
'Content-Type': 'application/json',
},
body: JSON.stringify({
templateId: 123,
data: {
globalAccessAuth: ['ACCOUNT'], // Require login
},
}),
});
```
### Disabling Direct Links
Temporarily disable a direct link without deleting it:
<Tabs items={['curl', 'TypeScript']}>
<Tab value="curl">
```bash
curl -X POST "https://app.documenso.com/api/v2/template/direct/toggle" \
-H "Authorization: api_xxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"templateId": 123,
"enabled": false
}'
```
</Tab>
<Tab value="TypeScript">
```typescript
const response = await fetch(`${BASE_URL}/template/direct/toggle`, {
method: 'POST',
headers: {
Authorization: API_TOKEN,
'Content-Type': 'application/json',
},
body: JSON.stringify({
templateId: 123,
enabled: false,
}),
});
```
</Tab>
</Tabs>
Re-enable later by setting `enabled: true`. The URL remains the same.
### Deleting Direct Links
Permanently remove a direct link:
```bash
curl -X POST "https://app.documenso.com/api/v2/template/direct/delete" \
-H "Authorization: api_xxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"templateId": 123
}'
```
<Callout type="warn">
Deleting a direct link invalidates the URL permanently. If you enable direct links again, a new
URL will be generated.
</Callout>
---
## Styling and Customization
### Branding
The signing experience uses your organisation's branding settings:
- Logo
- Primary color
- Email customization
Configure branding in **Settings** > **Branding** or via team settings.
### Signature Options
Control which signature input methods are available:
```typescript
const response = await fetch(`${BASE_URL}/template/update`, {
method: 'POST',
headers: {
Authorization: API_TOKEN,
'Content-Type': 'application/json',
},
body: JSON.stringify({
templateId: 123,
meta: {
typedSignatureEnabled: true, // Allow typed signatures
drawSignatureEnabled: true, // Allow drawn signatures
uploadSignatureEnabled: false, // Disable uploaded signatures
},
}),
});
```
### White-labeling
Enterprise plans support white-label embedding with the "Powered by Documenso" badge removed. [Contact sales](mailto:support@documenso.com) for details.
---
## Handling Completion
### Webhook Notifications
Set up webhooks to receive notifications when documents are signed:
```json
{
"event": "DOCUMENT_SIGNED",
"payload": {
"id": 123,
"externalId": "order-12345",
"title": "contract.pdf",
"status": "COMPLETED",
"Recipient": [
{
"email": "signer@example.com",
"name": "John Doe",
"signingStatus": "SIGNED",
"signedAt": "2024-01-15T10:30:00.000Z"
}
]
},
"createdAt": "2024-01-15T10:30:00.000Z",
"webhookEndpoint": "https://your-endpoint.com/webhook"
}
```
See [Webhooks](/docs/developers/webhooks) for setup instructions.
### Polling for Status
If webhooks aren't suitable, poll the document status:
```typescript
async function checkDocumentStatus(externalId: string) {
const response = await fetch(`${BASE_URL}/envelope?source=TEMPLATE_DIRECT_LINK`, {
headers: { Authorization: API_TOKEN },
});
const { data } = await response.json();
return data.find((doc) => doc.externalId === externalId);
}
```
---
## Complete Example
This example shows a complete workflow for embedding direct link signing:
```typescript
const API_TOKEN = process.env.DOCUMENSO_API_TOKEN;
const BASE_URL = 'https://app.documenso.com/api/v2';
// 1. Get template with direct link
async function getDirectLinkTemplate(templateId: number) {
const response = await fetch(`${BASE_URL}/template/${templateId}`, {
headers: { Authorization: API_TOKEN },
});
return response.json();
}
// 2. Create direct link if not exists
async function ensureDirectLink(templateId: number, recipientId: number) {
const template = await getDirectLinkTemplate(templateId);
if (template.directLink?.enabled) {
return template.directLink.token;
}
const response = await fetch(`${BASE_URL}/template/direct/create`, {
method: 'POST',
headers: {
Authorization: API_TOKEN,
'Content-Type': 'application/json',
},
body: JSON.stringify({
templateId,
directRecipientId: recipientId,
}),
});
const directLink = await response.json();
return directLink.token;
}
// 3. Generate signing URL with tracking
function getEmbedUrl(token: string, orderId: string) {
const params = new URLSearchParams({ externalId: orderId });
return `https://app.documenso.com/embed/direct/${token}?${params}`;
}
// Usage
const token = await ensureDirectLink(123, 1);
const embedUrl = getEmbedUrl(token, 'order-12345');
// Embed in your page
document.getElementById('signer-frame').src = embedUrl;
```
---
## See Also
- [SDKs](/docs/developers/embedding/sdks) - Framework SDK integration
- [Templates API](/docs/developers/api/templates) - Template management
- [Webhooks](/docs/developers/webhooks) - Event notifications
- [Direct Links (User Guide)](/docs/users/documents/direct-links) - End-user documentation
@@ -0,0 +1,242 @@
---
title: Embedding
description: Embed document signing experiences directly in your application using official SDKs.
---
import { Callout } from 'fumadocs-ui/components/callout';
import { Step, Steps } from 'fumadocs-ui/components/steps';
## Embedded Signing vs Embedded Authoring
Documenso offers two types of embedding:
- **Embedded Signing** lets you embed the signing experience in your application. Your users sign documents without leaving your site. Available on Teams Plan and above.
- **Embedded Authoring** lets you embed document and template _creation and editing_ in your application. This is an [Enterprise](/docs/policies/enterprise-edition) feature (also available as a Platform Plan add-on). See the [Authoring](/docs/developers/embedding/authoring) guide.
This page covers **embedded signing**. If you need your users to create or edit documents inside your app, see [Authoring](/docs/developers/embedding/authoring).
---
## Availability
Embedding is available on **Teams Plan** and above, as well as for **Early Adopters** within a team (Early Adopters can create a team for free).
The [Platform Plan](https://documen.so/platform-cta-pricing) adds enhanced customization:
- Custom CSS and styling variables
- Dark mode controls
- Removal of Documenso branding
---
## How It Works
There are two ways to embed signing, each using a different component and token type.
### Direct Templates
Direct templates are evergreen - each time a user completes signing, a new document is created from the template. This is the recommended approach for most use cases.
Use the `EmbedDirectTemplate` component with a template token:
```jsx
import { EmbedDirectTemplate } from '@documenso/embed-react';
<EmbedDirectTemplate
token="your-template-token"
onDocumentCompleted={(data) => {
console.log('Signed:', data.documentId);
}}
/>;
```
### Signing Tokens
For advanced integrations where you create documents via the API, you can embed the signing experience for a specific recipient using their signing token.
Use the `EmbedSignDocument` component with the recipient's token:
```jsx
import { EmbedSignDocument } from '@documenso/embed-react';
<EmbedSignDocument
token="recipient-signing-token"
onDocumentCompleted={(data) => {
console.log('Signed:', data.documentId);
}}
/>;
```
<Callout type="info">
For most use cases, direct templates are the way to go. Use signing tokens when you need
programmatic control over document creation via the API.
</Callout>
---
## Getting Your Token
### Direct Template Token
{/* prettier-ignore */}
<Steps>
<Step>
Navigate to your team's templates in Documenso
![Team Templates](/embedding/team-templates.png)
</Step>
<Step>
Click on a direct link template to copy its URL. The token is the last segment of the URL.
For example, `https://app.documenso.com/d/-WoSwWVT-fYOERS2MI37k` has the token `-WoSwWVT-fYOERS2MI37k`.
If your template is not a direct link template yet, select **Direct Link** from the three-dot menu on the templates table to enable it.
![Enable Direct Link Template](/embedding/enable-direct-link.png)
</Step>
</Steps>
### Signing Token
Signing tokens are returned in API responses when distributing a document. You can also get one manually by hovering over a recipient's avatar on a document you own and clicking their email.
![Copy Recipient Token](/embedding/copy-recipient-token.png)
---
## Framework SDKs
Pick your framework to get started:
<Cards>
<Card
title="React"
description="@documenso/embed-react"
href="/docs/developers/embedding/sdks/react"
/>
<Card title="Vue" description="@documenso/embed-vue" href="/docs/developers/embedding/sdks/vue" />
<Card
title="Svelte"
description="@documenso/embed-svelte"
href="/docs/developers/embedding/sdks/svelte"
/>
<Card
title="Angular"
description="@documenso/embed-angular"
href="/docs/developers/embedding/sdks/angular"
/>
<Card
title="Solid"
description="@documenso/embed-solid"
href="/docs/developers/embedding/sdks/solid"
/>
<Card
title="Preact"
description="@documenso/embed-preact"
href="/docs/developers/embedding/sdks/preact"
/>
</Cards>
A [Web Components](https://developer.mozilla.org/en-US/docs/Web/API/Web_components) SDK (`@documenso/embed-webcomponent`) is also available for use outside of JavaScript frameworks. It works in any environment that supports custom elements.
If you prefer not to use any SDK, you can embed signing using [Direct Links](/docs/developers/embedding/direct-links) with a plain iframe or redirect.
---
## Props
### EmbedDirectTemplate
| Prop | Type | Description |
| --------------------- | ---------- | ---------------------------------------------------------------- |
| `token` | `string` | **Required.** The direct template token. |
| `host` | `string` | Documenso instance URL. Defaults to `https://app.documenso.com`. |
| `name` | `string` | Pre-fill the signer's name. |
| `lockName` | `boolean` | Prevent the signer from changing their name. |
| `email` | `string` | Pre-fill the signer's email. |
| `lockEmail` | `boolean` | Prevent the signer from changing their email. |
| `externalId` | `string` | Your reference ID, stored with the created document. |
| `css` | `string` | Custom CSS string (Platform Plan). |
| `cssVars` | `object` | CSS variable overrides for theming (Platform Plan). |
| `darkModeDisabled` | `boolean` | Disable dark mode in the embed (Platform Plan). |
| `onDocumentReady` | `function` | Called when the document is loaded and ready. |
| `onDocumentCompleted` | `function` | Called when signing is completed. |
| `onDocumentError` | `function` | Called when an error occurs. |
| `onFieldSigned` | `function` | Called when a field is signed. |
| `onFieldUnsigned` | `function` | Called when a field value is cleared. |
### EmbedSignDocument
| Prop | Type | Description |
| --------------------- | ---------- | ---------------------------------------------------------------- |
| `token` | `string` | **Required.** The recipient's signing token. |
| `host` | `string` | Documenso instance URL. Defaults to `https://app.documenso.com`. |
| `name` | `string` | Pre-fill the signer's name. |
| `lockName` | `boolean` | Prevent the signer from changing their name. |
| `onDocumentReady` | `function` | Called when the document is loaded and ready. |
| `onDocumentCompleted` | `function` | Called when signing is completed. |
| `onDocumentError` | `function` | Called when an error occurs. |
---
## Event Callbacks
### onDocumentCompleted
Receives an object with:
| Field | Type | Description |
| ------------- | -------- | ------------------------------ |
| `token` | `string` | The token used for signing. |
| `documentId` | `number` | The ID of the signed document. |
| `recipientId` | `number` | The ID of the recipient. |
### onFieldSigned
Receives an object with:
| Field | Type | Description |
| ---------- | --------- | -------------------------------------------- |
| `fieldId` | `number` | The ID of the field. |
| `value` | `string` | The field value. |
| `isBase64` | `boolean` | Whether the value is a base64 encoded image. |
### onFieldUnsigned
Receives an object with:
| Field | Type | Description |
| --------- | -------- | -------------------- |
| `fieldId` | `number` | The ID of the field. |
---
## More
<Cards>
<Card
title="Direct Links"
description="Embed with iframes or redirects, no SDK required."
href="/docs/developers/embedding/direct-links"
/>
<Card
title="CSS Variables"
description="Customize colors, spacing, and theming."
href="/docs/developers/embedding/css-variables"
/>
<Card
title="Authoring"
description="Embed document and template creation."
href="/docs/developers/embedding/authoring"
/>
</Cards>
---
## See Also
- [Documents API](/docs/developers/api/documents) - Create documents programmatically
- [Templates API](/docs/developers/api/templates) - Manage templates via API
- [Webhooks](/docs/developers/webhooks) - Receive server-side signing notifications
@@ -0,0 +1,4 @@
{
"title": "Embedding",
"pages": ["sdks", "direct-links", "css-variables", "authoring"]
}
@@ -0,0 +1,92 @@
---
title: Angular
description: Embed Documenso signing in your Angular application using the official SDK.
---
import { Tab, Tabs } from 'fumadocs-ui/components/tabs';
## Installation
<Tabs items={['npm', 'yarn', 'pnpm']}>
<Tab value="npm">``` npm install @documenso/embed-angular ```</Tab>
<Tab value="yarn">``` yarn add @documenso/embed-angular ```</Tab>
<Tab value="pnpm">``` pnpm add @documenso/embed-angular ```</Tab>
</Tabs>
---
## Direct Template
```typescript
import { Component } from '@angular/core';
import { EmbedDirectTemplate } from '@documenso/embed-angular';
@Component({
selector: 'app-signing',
standalone: true,
imports: [EmbedDirectTemplate],
template: `
<embed-direct-template
[token]="token"
[name]="'John Doe'"
[email]="'john@example.com'"
[lockEmail]="true"
[externalId]="'order-12345'"
(documentReady)="onReady()"
(documentCompleted)="onCompleted($event)"
(documentError)="onError()"
/>
`,
})
export class SigningComponent {
token = 'your-template-token';
onReady() {
console.log('Ready');
}
onCompleted(data: { documentId: number }) {
console.log('Signed:', data.documentId);
}
onError() {
console.error('Error');
}
}
```
---
## Signing Token
```typescript
import { Component, Input } from '@angular/core';
import { EmbedSignDocument } from '@documenso/embed-angular';
@Component({
selector: 'app-signing',
standalone: true,
imports: [EmbedSignDocument],
template: `
<embed-sign-document
[token]="token"
(documentCompleted)="onCompleted($event)"
/>
`,
})
export class SigningComponent {
@Input() token = '';
onCompleted(data: { documentId: number }) {
console.log('Signed:', data.documentId);
}
}
```
---
## See Also
- [Embedding Overview](/docs/developers/embedding) - Props reference and concepts
- [CSS Variables](/docs/developers/embedding/css-variables) - Customize appearance
- [Authoring](/docs/developers/embedding/authoring) - Embed document creation
@@ -0,0 +1,37 @@
---
title: SDKs
description: Official embedding SDKs for React, Vue, Svelte, Angular, Solid, and Preact.
---
Install the SDK for your framework and embed document signing with a few lines of code.
<Cards>
<Card
title="React"
description="@documenso/embed-react"
href="/docs/developers/embedding/sdks/react"
/>
<Card title="Vue" description="@documenso/embed-vue" href="/docs/developers/embedding/sdks/vue" />
<Card
title="Svelte"
description="@documenso/embed-svelte"
href="/docs/developers/embedding/sdks/svelte"
/>
<Card
title="Angular"
description="@documenso/embed-angular"
href="/docs/developers/embedding/sdks/angular"
/>
<Card
title="Solid"
description="@documenso/embed-solid"
href="/docs/developers/embedding/sdks/solid"
/>
<Card
title="Preact"
description="@documenso/embed-preact"
href="/docs/developers/embedding/sdks/preact"
/>
</Cards>
If you are not using a JavaScript framework, you can embed signing using [Direct Links](/docs/developers/embedding/direct-links) with a plain iframe or redirect.
@@ -0,0 +1,4 @@
{
"title": "SDKs",
"pages": ["react", "vue", "svelte", "angular", "solid", "preact"]
}
@@ -0,0 +1,96 @@
---
title: Preact
description: Embed Documenso signing in your Preact application using the official SDK.
---
import { Tab, Tabs } from 'fumadocs-ui/components/tabs';
## Installation
<Tabs items={['npm', 'yarn', 'pnpm']}>
<Tab value="npm">``` npm install @documenso/embed-preact ```</Tab>
<Tab value="yarn">``` yarn add @documenso/embed-preact ```</Tab>
<Tab value="pnpm">``` pnpm add @documenso/embed-preact ```</Tab>
</Tabs>
---
## Direct Template
```tsx
import { EmbedDirectTemplate } from '@documenso/embed-preact';
const SigningPage = () => {
return (
<EmbedDirectTemplate
token="your-template-token"
name="John Doe"
email="john@example.com"
lockEmail={true}
externalId="order-12345"
onDocumentReady={() => console.log('Ready')}
onDocumentCompleted={(data) => {
console.log('Signed:', data.documentId);
}}
onDocumentError={() => console.error('Error')}
/>
);
};
```
---
## Signing Token
```tsx
import { EmbedSignDocument } from '@documenso/embed-preact';
const SigningPage = ({ token }: { token: string }) => {
return (
<EmbedSignDocument
token={token}
onDocumentCompleted={(data) => {
console.log('Signed:', data.documentId);
}}
/>
);
};
```
---
## Styling (Platform Plan)
```tsx
import { EmbedDirectTemplate } from '@documenso/embed-preact';
const StyledEmbed = () => {
return (
<EmbedDirectTemplate
token="your-token"
css={`
.documenso-embed {
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
`}
cssVars={{
primary: '#0000FF',
background: '#F5F5F5',
radius: '8px',
}}
darkModeDisabled={true}
/>
);
};
```
See [CSS Variables](/docs/developers/embedding/css-variables) for all available variables.
---
## See Also
- [Embedding Overview](/docs/developers/embedding) - Props reference and concepts
- [CSS Variables](/docs/developers/embedding/css-variables) - Customize appearance
- [Authoring](/docs/developers/embedding/authoring) - Embed document creation
@@ -0,0 +1,136 @@
---
title: React
description: Embed Documenso signing in your React application using the official SDK.
---
import { Tab, Tabs } from 'fumadocs-ui/components/tabs';
## Installation
<Tabs items={['npm', 'yarn', 'pnpm']}>
<Tab value="npm">``` npm install @documenso/embed-react ```</Tab>
<Tab value="yarn">``` yarn add @documenso/embed-react ```</Tab>
<Tab value="pnpm">``` pnpm add @documenso/embed-react ```</Tab>
</Tabs>
---
## Direct Template
```tsx
import { EmbedDirectTemplate } from '@documenso/embed-react';
const SigningPage = () => {
return (
<EmbedDirectTemplate
token="your-template-token"
name="John Doe"
email="john@example.com"
lockEmail={true}
externalId="order-12345"
onDocumentReady={() => console.log('Ready')}
onDocumentCompleted={(data) => {
console.log('Signed:', data.documentId);
}}
onDocumentError={() => console.error('Error')}
/>
);
};
```
---
## Signing Token
```tsx
import { EmbedSignDocument } from '@documenso/embed-react';
const SigningPage = ({ token }: { token: string }) => {
return (
<EmbedSignDocument
token={token}
onDocumentCompleted={(data) => {
console.log('Signed:', data.documentId);
}}
/>
);
};
```
---
## Styling (Platform Plan)
```tsx
import { EmbedDirectTemplate } from '@documenso/embed-react';
const StyledEmbed = () => {
return (
<EmbedDirectTemplate
token="your-token"
css={`
.documenso-embed {
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
`}
cssVars={{
primary: '#0000FF',
background: '#F5F5F5',
radius: '8px',
}}
darkModeDisabled={true}
/>
);
};
```
See [CSS Variables](/docs/developers/embedding/css-variables) for all available variables.
---
## Complete Example
```tsx
import { useState } from 'react';
import { EmbedDirectTemplate } from '@documenso/embed-react';
type Status = 'loading' | 'ready' | 'completed' | 'error';
const DocumentSigning = ({ token }: { token: string }) => {
const [status, setStatus] = useState<Status>('loading');
if (status === 'completed') {
return <p>Thank you for signing the document.</p>;
}
if (status === 'error') {
return <p>An error occurred. Please try again.</p>;
}
return (
<div style={{ position: 'relative', height: '100vh' }}>
{status === 'loading' && (
<div style={{ position: 'absolute', inset: 0, display: 'grid', placeItems: 'center' }}>
Loading...
</div>
)}
<EmbedDirectTemplate
token={token}
onDocumentReady={() => setStatus('ready')}
onDocumentCompleted={() => setStatus('completed')}
onDocumentError={() => setStatus('error')}
/>
</div>
);
};
```
---
## See Also
- [Embedding Overview](/docs/developers/embedding) - Props reference and concepts
- [CSS Variables](/docs/developers/embedding/css-variables) - Customize appearance
- [Authoring](/docs/developers/embedding/authoring) - Embed document creation
@@ -0,0 +1,96 @@
---
title: Solid
description: Embed Documenso signing in your Solid application using the official SDK.
---
import { Tab, Tabs } from 'fumadocs-ui/components/tabs';
## Installation
<Tabs items={['npm', 'yarn', 'pnpm']}>
<Tab value="npm">``` npm install @documenso/embed-solid ```</Tab>
<Tab value="yarn">``` yarn add @documenso/embed-solid ```</Tab>
<Tab value="pnpm">``` pnpm add @documenso/embed-solid ```</Tab>
</Tabs>
---
## Direct Template
```tsx
import { EmbedDirectTemplate } from '@documenso/embed-solid';
const SigningPage = () => {
return (
<EmbedDirectTemplate
token="your-template-token"
name="John Doe"
email="john@example.com"
lockEmail={true}
externalId="order-12345"
onDocumentReady={() => console.log('Ready')}
onDocumentCompleted={(data) => {
console.log('Signed:', data.documentId);
}}
onDocumentError={() => console.error('Error')}
/>
);
};
```
---
## Signing Token
```tsx
import { EmbedSignDocument } from '@documenso/embed-solid';
const SigningPage = (props: { token: string }) => {
return (
<EmbedSignDocument
token={props.token}
onDocumentCompleted={(data) => {
console.log('Signed:', data.documentId);
}}
/>
);
};
```
---
## Styling (Platform Plan)
```tsx
import { EmbedDirectTemplate } from '@documenso/embed-solid';
const StyledEmbed = () => {
return (
<EmbedDirectTemplate
token="your-token"
css={`
.documenso-embed {
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
`}
cssVars={{
primary: '#0000FF',
background: '#F5F5F5',
radius: '8px',
}}
darkModeDisabled={true}
/>
);
};
```
See [CSS Variables](/docs/developers/embedding/css-variables) for all available variables.
---
## See Also
- [Embedding Overview](/docs/developers/embedding) - Props reference and concepts
- [CSS Variables](/docs/developers/embedding/css-variables) - Customize appearance
- [Authoring](/docs/developers/embedding/authoring) - Embed document creation
@@ -0,0 +1,104 @@
---
title: Svelte
description: Embed Documenso signing in your Svelte application using the official SDK.
---
import { Tab, Tabs } from 'fumadocs-ui/components/tabs';
## Installation
<Tabs items={['npm', 'yarn', 'pnpm']}>
<Tab value="npm">``` npm install @documenso/embed-svelte ```</Tab>
<Tab value="yarn">``` yarn add @documenso/embed-svelte ```</Tab>
<Tab value="pnpm">``` pnpm add @documenso/embed-svelte ```</Tab>
</Tabs>
---
## Direct Template
```svelte
<script lang="ts">
import { EmbedDirectTemplate } from '@documenso/embed-svelte';
const token = 'your-template-token';
function onCompleted(data: { documentId: number }) {
console.log('Signed:', data.documentId);
}
</script>
<EmbedDirectTemplate
{token}
name="John Doe"
email="john@example.com"
lockEmail={true}
externalId="order-12345"
onDocumentReady={() => console.log('Ready')}
onDocumentCompleted={onCompleted}
onDocumentError={() => console.error('Error')}
/>
```
---
## Signing Token
```svelte
<script lang="ts">
import { EmbedSignDocument } from '@documenso/embed-svelte';
export let token: string;
function onCompleted(data: { documentId: number }) {
console.log('Signed:', data.documentId);
}
</script>
<EmbedSignDocument
{token}
onDocumentCompleted={onCompleted}
/>
```
---
## Styling (Platform Plan)
```svelte
<script lang="ts">
import { EmbedDirectTemplate } from '@documenso/embed-svelte';
const token = 'your-token';
const customCss = `
.documenso-embed {
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
`;
const cssVars = {
primary: '#0000FF',
background: '#F5F5F5',
radius: '8px',
};
</script>
<EmbedDirectTemplate
{token}
css={customCss}
cssVars={cssVars}
darkModeDisabled={true}
/>
```
See [CSS Variables](/docs/developers/embedding/css-variables) for all available variables.
---
## See Also
- [Embedding Overview](/docs/developers/embedding) - Props reference and concepts
- [CSS Variables](/docs/developers/embedding/css-variables) - Customize appearance
- [Authoring](/docs/developers/embedding/authoring) - Embed document creation
@@ -0,0 +1,107 @@
---
title: Vue
description: Embed Documenso signing in your Vue application using the official SDK.
---
import { Tab, Tabs } from 'fumadocs-ui/components/tabs';
## Installation
<Tabs items={['npm', 'yarn', 'pnpm']}>
<Tab value="npm">``` npm install @documenso/embed-vue ```</Tab>
<Tab value="yarn">``` yarn add @documenso/embed-vue ```</Tab>
<Tab value="pnpm">``` pnpm add @documenso/embed-vue ```</Tab>
</Tabs>
---
## Direct Template
```html
<script setup lang="ts">
import { EmbedDirectTemplate } from '@documenso/embed-vue';
const token = 'your-template-token';
function onCompleted(data: { documentId: number }) {
console.log('Signed:', data.documentId);
}
</script>
<template>
<EmbedDirectTemplate
:token="token"
name="John Doe"
email="john@example.com"
:lockEmail="true"
externalId="order-12345"
@document-completed="onCompleted"
@document-ready="() => console.log('Ready')"
@document-error="() => console.error('Error')"
/>
</template>
```
---
## Signing Token
```html
<script setup lang="ts">
import { EmbedSignDocument } from '@documenso/embed-vue';
const props = defineProps<{ token: string }>();
function onCompleted(data: { documentId: number }) {
console.log('Signed:', data.documentId);
}
</script>
<template>
<EmbedSignDocument :token="props.token" @document-completed="onCompleted" />
</template>
```
---
## Styling (Platform Plan)
```html
<script setup lang="ts">
import { EmbedDirectTemplate } from '@documenso/embed-vue';
const token = 'your-token';
const customCss = `
.documenso-embed {
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
`;
const cssVars = {
primary: '#0000FF',
background: '#F5F5F5',
radius: '8px',
};
</script>
<template>
<EmbedDirectTemplate
:token="token"
:css="customCss"
:cssVars="cssVars"
:darkModeDisabled="true"
/>
</template>
```
See [CSS Variables](/docs/developers/embedding/css-variables) for all available variables.
---
## See Also
- [Embedding Overview](/docs/developers/embedding) - Props reference and concepts
- [CSS Variables](/docs/developers/embedding/css-variables) - Customize appearance
- [Authoring](/docs/developers/embedding/authoring) - Embed document creation