diff --git a/.env.example b/.env.example index ed77d048a..b2dfb0805 100644 --- a/.env.example +++ b/.env.example @@ -27,6 +27,8 @@ NEXT_PRIVATE_OIDC_SKIP_VERIFY="" # [[URLS]] NEXT_PUBLIC_WEBAPP_URL="http://localhost:3000" NEXT_PUBLIC_MARKETING_URL="http://localhost:3001" +# URL used by the web app to request itself (e.g. local background jobs) +NEXT_PRIVATE_INTERNAL_WEBAPP_URL="http://localhost:3000" # [[DATABASE]] NEXT_PRIVATE_DATABASE_URL="postgres://documenso:password@127.0.0.1:54320/documenso" diff --git a/.github/actions/cache-build/action.yml b/.github/actions/cache-build/action.yml index e1eb4da22..056b9a193 100644 --- a/.github/actions/cache-build/action.yml +++ b/.github/actions/cache-build/action.yml @@ -3,7 +3,7 @@ description: 'Cache or restore if necessary' inputs: node_version: required: false - default: v18.x + default: v20.x runs: using: 'composite' steps: @@ -17,7 +17,7 @@ runs: **/.turbo/** **/dist/** - key: prod-build-${{ github.run_id }} + key: prod-build-${{ github.run_id }}-${{ hashFiles('package-lock.json') }} restore-keys: prod-build- - run: npm run build diff --git a/.github/actions/node-install/action.yml b/.github/actions/node-install/action.yml index 77483a9a4..59b542fc8 100644 --- a/.github/actions/node-install/action.yml +++ b/.github/actions/node-install/action.yml @@ -2,7 +2,7 @@ name: 'Setup node and cache node_modules' inputs: node_version: required: false - default: v18.x + default: v20.x runs: using: 'composite' diff --git a/.github/workflows/e2e-tests.yml b/.github/workflows/e2e-tests.yml index 22705c2d6..baa4c1f07 100644 --- a/.github/workflows/e2e-tests.yml +++ b/.github/workflows/e2e-tests.yml @@ -32,6 +32,9 @@ jobs: - name: Run Playwright tests run: npm run ci + env: + # Needed since we use next start which will set the NODE_ENV to production + NEXT_PRIVATE_SIGNING_LOCAL_FILE_PATH: './example/cert.p12' - uses: actions/upload-artifact@v4 if: always() diff --git a/.gitignore b/.gitignore index 3b0569b15..b95fcc7d2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,7 @@ # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. +packages/prisma/generated/types.ts + # dependencies node_modules .pnp diff --git a/README.md b/README.md index f32438800..178b1f0cf 100644 --- a/README.md +++ b/README.md @@ -303,6 +303,10 @@ WantedBy=multi-user.target [![Deploy to Koyeb](https://www.koyeb.com/static/images/deploy/button.svg)](https://app.koyeb.com/deploy?type=git&repository=github.com/documenso/documenso&branch=main&name=documenso-app&builder=dockerfile&dockerfile=/docker/Dockerfile) +## Elestio + +[![Deploy on Elestio](https://elest.io/images/logos/deploy-to-elestio-btn.png)](https://elest.io/open-source/documenso) + ## Troubleshooting ### I'm not receiving any emails when using the developer quickstart. diff --git a/apps/documentation/package.json b/apps/documentation/package.json index 0c555f39a..7ab519307 100644 --- a/apps/documentation/package.json +++ b/apps/documentation/package.json @@ -16,7 +16,7 @@ "@documenso/tailwind-config": "*", "@documenso/trpc": "*", "@documenso/ui": "*", - "next": "14.0.3", + "next": "14.2.6", "next-plausible": "^3.12.0", "nextra": "^2.13.4", "nextra-theme-docs": "^2.13.4", @@ -32,4 +32,4 @@ "tailwindcss": "^3.3.0", "typescript": "^5" } -} +} \ No newline at end of file diff --git a/apps/documentation/pages/developers/_meta.json b/apps/documentation/pages/developers/_meta.json index bb735320f..a9f3c3823 100644 --- a/apps/documentation/pages/developers/_meta.json +++ b/apps/documentation/pages/developers/_meta.json @@ -12,5 +12,6 @@ "title": "API & Integration Guides" }, "public-api": "Public API", + "embedding": "Embedding", "webhooks": "Webhooks" -} +} \ No newline at end of file diff --git a/apps/documentation/pages/developers/embedding/index.mdx b/apps/documentation/pages/developers/embedding/index.mdx new file mode 100644 index 000000000..383c9beb3 --- /dev/null +++ b/apps/documentation/pages/developers/embedding/index.mdx @@ -0,0 +1,131 @@ +--- +title: Get Started +description: Learn how to use embedding to bring signing to your own website or application +--- + +# Embedding + +Our embedding feature lets you integrate our document signing experience into your own application or website. Whether you're building with React, Preact, Vue, Svelte, Solid, or using generalized web components, this guide will help you get started with embedding Documenso. + +## Availability + +Embedding is currently available for all users on a **Teams Plan** and above, as well as **Early Adopter's** within a team (Early Adopters can create a team for free). + +In the future, we will roll out a **Platform Plan** that will offer additional enhancements for embedding, including the option to remove Documenso branding for a more customized experience. + +## How Embedding Works + +Embedding with Documenso allows you to handle document signing in two main ways: + +1. **Using Direct Templates**: Using direct templates you can have an evergreen template that upon completion will create a new document within Documenso. +2. **Using a Signing Token**: A more advanced option for those running rich integrations with Documenso already. Given a recipients signing token you can embed the signing experience in your application rather than direct the recipient to Documenso. + +_For most use-cases we recommend using direct templates, however if you have a need for a more advanced integration, we are happy to help you get started._ + +## Supported Frameworks + +We support embedding across a range of popular JavaScript frameworks, including: + +| Framework | Package | +| --------- | -------------------------------------------------------------------------------- | +| React | [@documenso/embed-react](https://www.npmjs.com/package/@documenso/embed-react) | +| Preact | [@documenso/embed-preact](https://www.npmjs.com/package/@documenso/embed-preact) | +| Vue | [@documenso/embed-vue](https://www.npmjs.com/package/@documenso/embed-vue) | +| Svelte | [@documenso/embed-svelte](https://www.npmjs.com/package/@documenso/embed-svelte) | +| Solid | [@documenso/embed-solid](https://www.npmjs.com/package/@documenso/embed-solid) | + +Additionally, we provide **web components** for more generalized use. However, please note that web components are still in their early stages and haven't been extensively tested. + +## Embedding with Direct Templates + +#### Instructions + +To get started with embedding using a Direct Template we will need the URL segment which is also referred to as the token for the template. + +You can find your URL/Token by performing the following steps: + +1. **Navigate to your team's templates within Documenso** + +![Team Templates](/embedding/team-templates.png) + +2. **Click on the direct link template you want to embed** + +This will copy the URL to your clipboard, e.g. `https://stg-app.documenso.com/d/-WoSwWVT-fYOERS2MI37k` + +**For the above url the token is `-WoSwWVT-fYOERS2MI37k`** + +3. Provide the token to the `EmbedDirectTemplate` component in your frameworks SDK + +```jsx +import { EmbedDirectTemplate } from '@documenso/embed-react'; + +const MyEmbeddingComponent = () => { + const token = 'YOUR_TOKEN_HERE'; // Replace with the actual token + + return ; +}; +``` + +--- + +**Converting a regular template to a direct link template** + +If you don't currently have any direct link templates you can easily create one by selecting the "Direct Link" option within the actions dropdown on the templates table. + +This will show a dialog which will ask you to configure which recipient should be used as the direct link signer. + +![Enable Direct Link Template](/embedding/enable-direct-link.png) + +--- + +## Embedding with Signing Tokens + +To embed the signing process for an ordinary document, you’ll need a **document signing token** for the recipient. This token provides the necessary access to load the document and facilitate the signing process securely. + +#### Instructions + +1. Retrieve the signing token for the recipient document you want to embed + +This will typically be done using an API integration where signing tokens are provided as part of the response when creating a document. Alternatively you can manually get a signing link by clicking hovering over a recipients avatar and clicking their email on a document that you own. + +![Copy Recipient Token](/embedding/copy-recipient-token.png) + +With the signing url on our clipboard we can extract the token the same way we did for the direct link template. + +So `https://stg-app.documenso.com/sign/lm7Tp2_yhvFfzdeJQzYQF` will become `lm7Tp2_yhvFfzdeJQzYQF` + +2. Provide the token to the `EmbedSignDocument` component in your frameworks SDK + +```jsx +import { EmbedSignDocument } from '@documenso/embed-react'; + +const MyEmbeddingComponent = () => { + const token = 'YOUR_TOKEN_HERE'; // Replace with the actual token + + return ; +}; +``` + +--- + +## Using Embedding in Your Application + +Once you've obtained the appropriate tokens, you can integrate the signing experience into your application. For framework-specific instructions, please refer to the guides provided in our documentation for: + +- [React](/developers/embedding/react) +- [Preact](/developers/embedding/preact) +- [Vue](/developers/embedding/vue) +- [Svelte](/developers/embedding/svelte) +- [Solid](/developers/embedding/solid) + +If you're using **web components**, the integration process is slightly different. Keep in mind that web components are currently less tested but can still provide flexibility for general use cases. + +## Stay Tuned for the Platform Plan + +While embedding is already a powerful tool, we're working on a **Platform Plan** that will introduce even more functionality. This plan will offer: + +- Additional customization options +- The ability to remove Documenso branding +- Additional controls for the signing experience + +More details will be shared as we approach the release. diff --git a/apps/documentation/pages/developers/embedding/preact.mdx b/apps/documentation/pages/developers/embedding/preact.mdx new file mode 100644 index 000000000..808b3aa49 --- /dev/null +++ b/apps/documentation/pages/developers/embedding/preact.mdx @@ -0,0 +1,77 @@ +--- +title: Preact Integration +description: Learn how to use our embedding SDK within your Preact application. +--- + +# Preact Integration + +Our Preact SDK provides a simple way to embed a signing experience within your Preact application. It supports both direct link templates and signing tokens. + +## Installation + +To install the SDK, run the following command: + +```bash +npm install @documenso/embed-preact +``` + +## Usage + +To embed a signing experience, you'll need to provide the token for the document you want to embed. This can be done in a few different ways, depending on your use case. + +### Direct Link Template + +If you have a direct link template, you can simply provide the token for the template to the `EmbedDirectTemplate` component. + +```jsx +import { EmbedDirectTemplate } from '@documenso/embed-preact'; + +const MyEmbeddingComponent = () => { + const token = 'YOUR_TOKEN_HERE'; // Replace with the actual token + + return ; +}; +``` + +#### Props + +| Prop | Type | Description | +| ------------------- | ------------------- | ------------------------------------------------------------------------------------------ | +| token | string | The token for the document you want to embed | +| host | string (optional) | The host to be used for the signing experience, relevant for self-hosters | +| name | string (optional) | The name the signer that will be used by default for signing | +| lockName | boolean (optional) | Whether or not the name field should be locked disallowing modifications | +| email | string (optional) | The email the signer that will be used by default for signing | +| lockEmail | boolean (optional) | Whether or not the email field should be locked disallowing modifications | +| externalId | string (optional) | The external ID to be used for the document that will be created upon completion | +| onDocumentReady | function (optional) | A callback function that will be called when the document is loaded and ready to be signed | +| onDocumentCompleted | function (optional) | A callback function that will be called when the document has been completed | +| onDocumentError | function (optional) | A callback function that will be called when an error occurs with the document | +| onFieldSigned | function (optional) | A callback function that will be called when a field has been signed | +| onFieldUnsigned | function (optional) | A callback function that will be called when a field has been unsigned | + +### Signing Token + +If you have a signing token, you can provide it to the `EmbedSignDocument` component. + +```jsx +import { EmbedSignDocument } from '@documenso/embed-preact'; + +const MyEmbeddingComponent = () => { + const token = 'YOUR_TOKEN_HERE'; // Replace with the actual token + + return ; +}; +``` + +#### Props + +| Prop | Type | Description | +| ------------------- | ------------------- | ------------------------------------------------------------------------------------------ | +| token | string | The token for the document you want to embed | +| host | string (optional) | The host to be used for the signing experience, relevant for self-hosters | +| name | string (optional) | The name the signer that will be used by default for signing | +| lockName | boolean (optional) | Whether or not the name field should be locked disallowing modifications | +| onDocumentReady | function (optional) | A callback function that will be called when the document is loaded and ready to be signed | +| onDocumentCompleted | function (optional) | A callback function that will be called when the document has been completed | +| onDocumentError | function (optional) | A callback function that will be called when an error occurs with the document | diff --git a/apps/documentation/pages/developers/embedding/react.mdx b/apps/documentation/pages/developers/embedding/react.mdx new file mode 100644 index 000000000..7ba19474f --- /dev/null +++ b/apps/documentation/pages/developers/embedding/react.mdx @@ -0,0 +1,77 @@ +--- +title: React Integration +description: Learn how to use our embedding SDK within your React application. +--- + +# React Integration + +Our React SDK provides a simple way to embed a signing experience within your React application. It supports both direct link templates and signing tokens. + +## Installation + +To install the SDK, run the following command: + +```bash +npm install @documenso/embed-react +``` + +## Usage + +To embed a signing experience, you'll need to provide the token for the document you want to embed. This can be done in a few different ways, depending on your use case. + +### Direct Link Template + +If you have a direct link template, you can simply provide the token for the template to the `EmbedDirectTemplate` component. + +```jsx +import { EmbedDirectTemplate } from '@documenso/embed-react'; + +const MyEmbeddingComponent = () => { + const token = 'YOUR_TOKEN_HERE'; // Replace with the actual token + + return ; +}; +``` + +#### Props + +| Prop | Type | Description | +| ------------------- | ------------------- | ------------------------------------------------------------------------------------------ | +| token | string | The token for the document you want to embed | +| host | string (optional) | The host to be used for the signing experience, relevant for self-hosters | +| name | string (optional) | The name the signer that will be used by default for signing | +| lockName | boolean (optional) | Whether or not the name field should be locked disallowing modifications | +| email | string (optional) | The email the signer that will be used by default for signing | +| lockEmail | boolean (optional) | Whether or not the email field should be locked disallowing modifications | +| externalId | string (optional) | The external ID to be used for the document that will be created upon completion | +| onDocumentReady | function (optional) | A callback function that will be called when the document is loaded and ready to be signed | +| onDocumentCompleted | function (optional) | A callback function that will be called when the document has been completed | +| onDocumentError | function (optional) | A callback function that will be called when an error occurs with the document | +| onFieldSigned | function (optional) | A callback function that will be called when a field has been signed | +| onFieldUnsigned | function (optional) | A callback function that will be called when a field has been unsigned | + +### Signing Token + +If you have a signing token, you can provide it to the `EmbedSignDocument` component. + +```jsx +import { EmbedSignDocument } from '@documenso/embed-react'; + +const MyEmbeddingComponent = () => { + const token = 'YOUR_TOKEN_HERE'; // Replace with the actual token + + return ; +}; +``` + +#### Props + +| Prop | Type | Description | +| ------------------- | ------------------- | ------------------------------------------------------------------------------------------ | +| token | string | The token for the document you want to embed | +| host | string (optional) | The host to be used for the signing experience, relevant for self-hosters | +| name | string (optional) | The name the signer that will be used by default for signing | +| lockName | boolean (optional) | Whether or not the name field should be locked disallowing modifications | +| onDocumentReady | function (optional) | A callback function that will be called when the document is loaded and ready to be signed | +| onDocumentCompleted | function (optional) | A callback function that will be called when the document has been completed | +| onDocumentError | function (optional) | A callback function that will be called when an error occurs with the document | diff --git a/apps/documentation/pages/developers/embedding/solid.mdx b/apps/documentation/pages/developers/embedding/solid.mdx new file mode 100644 index 000000000..7feab2034 --- /dev/null +++ b/apps/documentation/pages/developers/embedding/solid.mdx @@ -0,0 +1,77 @@ +--- +title: Solid.js Integration +description: Learn how to use our embedding SDK within your Solid.js application. +--- + +# Solid.js Integration + +Our Solid.js SDK provides a simple way to embed a signing experience within your Solid.js application. It supports both direct link templates and signing tokens. + +## Installation + +To install the SDK, run the following command: + +```bash +npm install @documenso/embed-solid +``` + +## Usage + +To embed a signing experience, you'll need to provide the token for the document you want to embed. This can be done in a few different ways, depending on your use case. + +### Direct Link Template + +If you have a direct link template, you can simply provide the token for the template to the `EmbedDirectTemplate` component. + +```jsx +import { EmbedDirectTemplate } from '@documenso/embed-solid'; + +const MyEmbeddingComponent = () => { + const token = 'YOUR_TOKEN_HERE'; // Replace with the actual token + + return ; +}; +``` + +#### Props + +| Prop | Type | Description | +| ------------------- | ------------------- | ------------------------------------------------------------------------------------------ | +| token | string | The token for the document you want to embed | +| host | string (optional) | The host to be used for the signing experience, relevant for self-hosters | +| name | string (optional) | The name the signer that will be used by default for signing | +| lockName | boolean (optional) | Whether or not the name field should be locked disallowing modifications | +| email | string (optional) | The email the signer that will be used by default for signing | +| lockEmail | boolean (optional) | Whether or not the email field should be locked disallowing modifications | +| externalId | string (optional) | The external ID to be used for the document that will be created upon completion | +| onDocumentReady | function (optional) | A callback function that will be called when the document is loaded and ready to be signed | +| onDocumentCompleted | function (optional) | A callback function that will be called when the document has been completed | +| onDocumentError | function (optional) | A callback function that will be called when an error occurs with the document | +| onFieldSigned | function (optional) | A callback function that will be called when a field has been signed | +| onFieldUnsigned | function (optional) | A callback function that will be called when a field has been unsigned | + +### Signing Token + +If you have a signing token, you can provide it to the `EmbedSignDocument` component. + +```jsx +import { EmbedSignDocument } from '@documenso/embed-solid'; + +const MyEmbeddingComponent = () => { + const token = 'YOUR_TOKEN_HERE'; // Replace with the actual token + + return ; +}; +``` + +#### Props + +| Prop | Type | Description | +| ------------------- | ------------------- | ------------------------------------------------------------------------------------------ | +| token | string | The token for the document you want to embed | +| host | string (optional) | The host to be used for the signing experience, relevant for self-hosters | +| name | string (optional) | The name the signer that will be used by default for signing | +| lockName | boolean (optional) | Whether or not the name field should be locked disallowing modifications | +| onDocumentReady | function (optional) | A callback function that will be called when the document is loaded and ready to be signed | +| onDocumentCompleted | function (optional) | A callback function that will be called when the document has been completed | +| onDocumentError | function (optional) | A callback function that will be called when an error occurs with the document | diff --git a/apps/documentation/pages/developers/embedding/svelte.mdx b/apps/documentation/pages/developers/embedding/svelte.mdx new file mode 100644 index 000000000..d6a9abcf6 --- /dev/null +++ b/apps/documentation/pages/developers/embedding/svelte.mdx @@ -0,0 +1,79 @@ +--- +title: Svelte Integration +description: Learn how to use our embedding SDK within your Svelte application. +--- + +# Svelte Integration + +Our Svelte SDK provides a simple way to embed a signing experience within your Svelte application. It supports both direct link templates and signing tokens. + +## Installation + +To install the SDK, run the following command: + +```bash +npm install @documenso/embed-svelte +``` + +## Usage + +To embed a signing experience, you'll need to provide the token for the document you want to embed. This can be done in a few different ways, depending on your use case. + +### Direct Link Template + +If you have a direct link template, you can simply provide the token for the template to the `EmbedDirectTemplate` component. + +```html + + + +``` + +#### Props + +| Prop | Type | Description | +| ------------------- | ------------------- | ------------------------------------------------------------------------------------------ | +| token | string | The token for the document you want to embed | +| host | string (optional) | The host to be used for the signing experience, relevant for self-hosters | +| name | string (optional) | The name the signer that will be used by default for signing | +| lockName | boolean (optional) | Whether or not the name field should be locked disallowing modifications | +| email | string (optional) | The email the signer that will be used by default for signing | +| lockEmail | boolean (optional) | Whether or not the email field should be locked disallowing modifications | +| externalId | string (optional) | The external ID to be used for the document that will be created upon completion | +| onDocumentReady | function (optional) | A callback function that will be called when the document is loaded and ready to be signed | +| onDocumentCompleted | function (optional) | A callback function that will be called when the document has been completed | +| onDocumentError | function (optional) | A callback function that will be called when an error occurs with the document | +| onFieldSigned | function (optional) | A callback function that will be called when a field has been signed | +| onFieldUnsigned | function (optional) | A callback function that will be called when a field has been unsigned | + +### Signing Token + +If you have a signing token, you can provide it to the `EmbedSignDocument` component. + +```jsx +import { EmbedSignDocument } from '@documenso/embed-svelte'; + +const MyEmbeddingComponent = () => { + const token = 'YOUR_TOKEN_HERE'; // Replace with the actual token + + return ; +}; +``` + +#### Props + +| Prop | Type | Description | +| ------------------- | ------------------- | ------------------------------------------------------------------------------------------ | +| token | string | The token for the document you want to embed | +| host | string (optional) | The host to be used for the signing experience, relevant for self-hosters | +| name | string (optional) | The name the signer that will be used by default for signing | +| lockName | boolean (optional) | Whether or not the name field should be locked disallowing modifications | +| onDocumentReady | function (optional) | A callback function that will be called when the document is loaded and ready to be signed | +| onDocumentCompleted | function (optional) | A callback function that will be called when the document has been completed | +| onDocumentError | function (optional) | A callback function that will be called when an error occurs with the document | diff --git a/apps/documentation/pages/developers/embedding/vue.mdx b/apps/documentation/pages/developers/embedding/vue.mdx new file mode 100644 index 000000000..588de28b0 --- /dev/null +++ b/apps/documentation/pages/developers/embedding/vue.mdx @@ -0,0 +1,79 @@ +--- +title: Vue Integration +description: Learn how to use our embedding SDK within your Vue application. +--- + +# Vue Integration + +Our Vue SDK provides a simple way to embed a signing experience within your Vue application. It supports both direct link templates and signing tokens. + +## Installation + +To install the SDK, run the following command: + +```bash +npm install @documenso/embed-vue +``` + +## Usage + +To embed a signing experience, you'll need to provide the token for the document you want to embed. This can be done in a few different ways, depending on your use case. + +### Direct Link Template + +If you have a direct link template, you can simply provide the token for the template to the `EmbedDirectTemplate` component. + +```html + + + +``` + +#### Props + +| Prop | Type | Description | +| ------------------- | ------------------- | ------------------------------------------------------------------------------------------ | +| token | string | The token for the document you want to embed | +| host | string (optional) | The host to be used for the signing experience, relevant for self-hosters | +| name | string (optional) | The name the signer that will be used by default for signing | +| lockName | boolean (optional) | Whether or not the name field should be locked disallowing modifications | +| email | string (optional) | The email the signer that will be used by default for signing | +| lockEmail | boolean (optional) | Whether or not the email field should be locked disallowing modifications | +| externalId | string (optional) | The external ID to be used for the document that will be created upon completion | +| onDocumentReady | function (optional) | A callback function that will be called when the document is loaded and ready to be signed | +| onDocumentCompleted | function (optional) | A callback function that will be called when the document has been completed | +| onDocumentError | function (optional) | A callback function that will be called when an error occurs with the document | +| onFieldSigned | function (optional) | A callback function that will be called when a field has been signed | +| onFieldUnsigned | function (optional) | A callback function that will be called when a field has been unsigned | + +### Signing Token + +If you have a signing token, you can provide it to the `EmbedSignDocument` component. + +```jsx +import { EmbedSignDocument } from '@documenso/embed-vue'; + +const MyEmbeddingComponent = () => { + const token = 'YOUR_TOKEN_HERE'; // Replace with the actual token + + return ; +}; +``` + +#### Props + +| Prop | Type | Description | +| ------------------- | ------------------- | ------------------------------------------------------------------------------------------ | +| token | string | The token for the document you want to embed | +| host | string (optional) | The host to be used for the signing experience, relevant for self-hosters | +| name | string (optional) | The name the signer that will be used by default for signing | +| lockName | boolean (optional) | Whether or not the name field should be locked disallowing modifications | +| onDocumentReady | function (optional) | A callback function that will be called when the document is loaded and ready to be signed | +| onDocumentCompleted | function (optional) | A callback function that will be called when the document has been completed | +| onDocumentError | function (optional) | A callback function that will be called when an error occurs with the document | diff --git a/apps/documentation/pages/developers/local-development/_meta.json b/apps/documentation/pages/developers/local-development/_meta.json index ff9f44207..725e5e278 100644 --- a/apps/documentation/pages/developers/local-development/_meta.json +++ b/apps/documentation/pages/developers/local-development/_meta.json @@ -3,5 +3,6 @@ "quickstart": "Developer Quickstart", "manual": "Manual Setup", "gitpod": "Gitpod", - "signing-certificate": "Signing Certificate" -} + "signing-certificate": "Signing Certificate", + "translations": "Translations" +} \ No newline at end of file diff --git a/apps/documentation/pages/developers/local-development/translations.mdx b/apps/documentation/pages/developers/local-development/translations.mdx new file mode 100644 index 000000000..a776dc50c --- /dev/null +++ b/apps/documentation/pages/developers/local-development/translations.mdx @@ -0,0 +1,128 @@ +--- +title: Translations +description: Handling translations in code. +--- + +# About + +Documenso uses the following stack to handle translations: + +- [Lingui](https://lingui.dev/) - React i10n library +- [Crowdin](https://crowdin.com/) - Handles syncing translations +- [OpenAI](https://openai.com/) - Provides AI translations + +Additional reading can be found in the [Lingui documentation](https://lingui.dev/introduction). + +## Requirements + +You **must** insert **`setupI18nSSR()`** when creating any of the following files: + +- Server layout.tsx +- Server page.tsx +- Server loading.tsx + +Server meaning it does not have `'use client'` in it. + +```tsx +import { setupI18nSSR } from '@documenso/lib/client-only/providers/i18n.server'; + +export default function SomePage() { + setupI18nSSR(); // Required if there are translations within the page, or nested in components. + + // Rest of code... +} +``` + +Additional information can be found [here.](https://lingui.dev/tutorials/react-rsc#pages-layouts-and-lingui) + +## Quick guide + +If you require more in-depth information, please see the [Lingui documentation](https://lingui.dev/introduction). + +### HTML + +Wrap all text to translate in **``** tags exported from **@lingui/macro** (not @lingui/react). + +```html +

+ Title +

+``` + +For text that is broken into elements, but represent a whole sentence, you must wrap it in a Trans tag so ensure the full message is extracted correctly. + +```html +

+ + This is one + full + sentence + +

+``` + +### Constants outside of react components + +```tsx +import { Trans, msg } from '@lingui/macro'; +import { useLingui } from '@lingui/react'; + +// Wrap text in msg`text to translate` when it's in a constant here, or another file/package. +export const CONSTANT_WITH_MSG = { + foo: msg`Hello`, + bar: msg`World`, +}; + +export const SomeComponent = () => { + const { _ } = useLingui(); + + return ( +
+ {/* This will render the correct translated text. */} +

{_(CONSTANT_WITH_MSG.foo)}

+
+ ); +}; +``` + +### Plurals + +Lingui provides a Plural component to make it easy. See full documentation [here.](https://lingui.dev/ref/macro#plural-1) + +```tsx +// Basic usage. + +``` + +### Dates + +Lingui provides a [DateTime instance](https://lingui.dev/ref/core#i18n.date) with the configured locale. + +#### Server components + +Note that the i18n instance is coming from **setupI18nSSR**. + +```tsx +import { Trans } from '@lingui/macro'; +import { useLingui } from '@lingui/react'; + +export const SomeComponent = () => { + const { i18n } = setupI18nSSR(); + + return The current date is {i18n.date(new Date(), { dateStyle: 'short' })}; +}; +``` + +#### Client components + +Note that the i18n instance is coming from the **import**. + +```tsx +import { i18n } from '@lingui/core'; +import { Trans } from '@lingui/macro'; +import { useLingui } from '@lingui/react'; + +export const SomeComponent = () => { + return The current date is {i18n.date(new Date(), { dateStyle: 'short' })}; +}; +``` diff --git a/apps/documentation/pages/developers/self-hosting/how-to.mdx b/apps/documentation/pages/developers/self-hosting/how-to.mdx index 2acbf9abb..a316b02b1 100644 --- a/apps/documentation/pages/developers/self-hosting/how-to.mdx +++ b/apps/documentation/pages/developers/self-hosting/how-to.mdx @@ -5,6 +5,8 @@ description: Learn how to self-host Documenso on your server or cloud infrastruc import { Callout, Steps } from 'nextra/components'; +import { CallToAction } from '@documenso/ui/components/call-to-action'; + # Self Hosting We support various deployment methods and are actively working on adding more. Please let us know if you have a specific deployment method in mind! @@ -273,3 +275,5 @@ We offer several alternative deployment methods for Documenso if you need more o ## Koyeb [![Deploy to Koyeb](https://www.koyeb.com/static/images/deploy/button.svg)](https://app.koyeb.com/deploy?type=git&repository=github.com/documenso/documenso&branch=main&name=documenso-app&builder=dockerfile&dockerfile=/docker/Dockerfile) + + diff --git a/apps/documentation/pages/developers/self-hosting/index.mdx b/apps/documentation/pages/developers/self-hosting/index.mdx index 84cbed30b..b4aefb848 100644 --- a/apps/documentation/pages/developers/self-hosting/index.mdx +++ b/apps/documentation/pages/developers/self-hosting/index.mdx @@ -3,6 +3,10 @@ title: Getting Started with Self-Hosting description: A step-by-step guide to setting up and hosting your own Documenso instance. --- +import { CallToAction } from '@documenso/ui/components/call-to-action'; + # Getting Started with Self-Hosting This is a step-by-step guide to setting up and hosting your own Documenso instance. Before getting started, [select the right license for you](/users/licenses). + + diff --git a/apps/documentation/pages/users/signing-documents/fields.mdx b/apps/documentation/pages/users/signing-documents/fields.mdx index bf02dd058..005ed2595 100644 --- a/apps/documentation/pages/users/signing-documents/fields.mdx +++ b/apps/documentation/pages/users/signing-documents/fields.mdx @@ -15,7 +15,7 @@ The signature field collects the signer's signature. It's required for each reci The field doesn't have any additional settings. You just need to place it on the document where you want the signer to sign. -![The signature field in the Documenso document editor](public/document-signing/signature-field-document-editor-view.webp) +![The signature field in the Documenso document editor](/document-signing/signature-field-document-editor-view.webp) ### Document Signing View @@ -23,11 +23,11 @@ The recipient will see the signature field when they open the document to sign. The recipient must click on the signature field to open the signing view, where they can sign using their mouse, touchpad, or touchscreen. -![The signature field in the Documenso document signing view](public/document-signing/signature-field-document-signing-view.webp) +![The signature field in the Documenso document signing view](/document-signing/signature-field-document-signing-view.webp) The image below shows the signature field signed by the recipient. -![The signature field signed by the user in the Documenso document signing view](public/document-signing/signed-signature-field.webp) +![The signature field signed by the user in the Documenso document signing view](/document-signing/signed-signature-field.webp) After signing, the recipient can click the "Complete" button to complete the signing process. @@ -39,7 +39,7 @@ The email field is used to collect the signer's email address. The field doesn't have any additional settings. You just need to place it on the document where you want the signer to sign. -![The email field in the Documenso document editor](public/document-signing/email-field-document-editor-view.webp) +![The email field in the Documenso document editor](/document-signing/email-field-document-editor-view.webp) ### Document Signing View @@ -47,11 +47,11 @@ When the recipient opens the document to sign, they will see the email field. The recipient must click on the email field to automatically sign the field with the email associated with their account. -![The email field in the Documenso document signing view](public/document-signing/email-field-document-signing-view.webp) +![The email field in the Documenso document signing view](/document-signing/email-field-document-signing-view.webp) The image below shows the email field signed by the recipient. -![The email field signed by the user in the Documenso document signing view](public/document-signing/signed-email-field.webp) +![The email field signed by the user in the Documenso document signing view](/document-signing/signed-email-field.webp) After entering their email address, the recipient can click the "Complete" button to complete the signing process. @@ -63,7 +63,7 @@ The name field is used to collect the signer's name. The field doesn't have any additional settings. You just need to place it on the document where you want the signer to sign. -![The name field in the Documenso document editor](public/document-signing/name-field-document-editor-view.webp) +![The name field in the Documenso document editor](/document-signing/name-field-document-editor-view.webp) ### Document Signing View @@ -71,11 +71,11 @@ When the recipient opens the document to sign, they will see the name field. The recipient must click on the name field, which will automatically sign the field with the name associated with their account. -![The name field in the Documenso document signing view](public/document-signing/name-field-document-signing-view.webp) +![The name field in the Documenso document signing view](/document-signing/name-field-document-signing-view.webp) The image below shows the name field signed by the recipient. -![The name field signed by the user in the Documenso document signing view](public/document-signing/name-field-signed.webp) +![The name field signed by the user in the Documenso document signing view](/document-signing/name-field-signed.webp) After entering their name, the recipient can click the "Complete" button to complete the signing process. @@ -87,7 +87,7 @@ The date field is used to collect the date of the signature. The field doesn't have any additional settings. You just need to place it on the document where you want the signer to sign. -![The date field in the Documenso document editor](public/document-signing/date-field-document-editor-view.webp) +![The date field in the Documenso document editor](/document-signing/date-field-document-editor-view.webp) ### Document Signing View @@ -95,11 +95,11 @@ When the recipient opens the document to sign, they will see the date field. The recipient must click on the date field to automatically sign the field with the current date and time. -![The date field in the Documenso document signing view](public/document-signing/date-field-document-signing-view.webp) +![The date field in the Documenso document signing view](/document-signing/date-field-document-signing-view.webp) The image below shows the date field signed by the recipient. -![The date field signed by the user in the Documenso document signing view](public/document-signing/date-field-signed.webp) +![The date field signed by the user in the Documenso document signing view](/document-signing/date-field-signed.webp) After entering the date, the recipient can click the "Complete" button to complete the signing process. @@ -111,11 +111,11 @@ The text field is used to collect text input from the signer. Place the text field on the document where you want the signer to enter text. The text field comes with additional settings that can be configured. -![The text field in the Documenso document editor](public/document-signing/text-field-document-editor-view.webp) +![The text field in the Documenso document editor](/document-signing/text-field-document-editor-view.webp) To open the settings, click on the text field and then on the "Sliders" icon. That opens the settings panel on the right side of the screen. -![The text field settings in the Documenso document editor](public/document-signing/text-field-advanced-settings-document-editor-view.webp) +![The text field settings in the Documenso document editor](/document-signing/text-field-advanced-settings-document-editor-view.webp) The text field settings include: @@ -137,7 +137,7 @@ It also comes with a couple of rules: Let's look at the following example. -![A text field with the settings configured by the user in the Documenso document editor](public/document-signing/text-field-with-filled-advanced-settings.webp) +![A text field with the settings configured by the user in the Documenso document editor](/document-signing/text-field-with-filled-advanced-settings.webp) The field is configured as follows: @@ -156,23 +156,23 @@ What the recipient sees when they open the document to sign depends on the setti In this case, the recipient sees the text field signed with the default value. -![Text field with the default value signed by the user in the Documenso document signing view](public/document-signing/text-field-autosigned.webp) +![Text field with the default value signed by the user in the Documenso document signing view](/document-signing/text-field-autosigned.webp) The recipient can modify the text field value since the field is not read-only. To change the value, the recipient must click the field to un-sign it. Once it's unsigned, the field uses the label set by the sender. -![Unsigned text field in the Documenso document signing view](public/document-signing/text-field-unsigned.webp) +![Unsigned text field in the Documenso document signing view](/document-signing/text-field-unsigned.webp) To sign the field with a different value, the recipient needs to click on the field and enter the new value. -![Text field with the text input in the Documenso document signing view](public/document-signing/text-field-input-modal.webp) +![Text field with the text input in the Documenso document signing view](/document-signing/text-field-input-modal.webp) Since the text field has a character limit, the recipient must enter a value that doesn't exceed the limit. Otherwise, an error message will appear, and the field will not be signed. The image below illustrates the text field signed with a new value. -![Text field signed with a new value](public/document-signing/text-field-new-value-signed.webp) +![Text field signed with a new value](/document-signing/text-field-new-value-signed.webp) After signing the field, the recipient can click the "Complete" button to complete the signing process. @@ -184,11 +184,11 @@ The number field is used for collecting a number input from the signer. Place the number field on the document where you want the signer to enter a number. The number field comes with additional settings that can be configured. -![The number field in the Documenso document editor](public/document-signing/number-field-document-editor.webp) +![The number field in the Documenso document editor](/document-signing/number-field-document-editor.webp) To open the settings, click on the number field and then on the "Sliders" icon. That opens the settings panel on the right side of the screen. -![The number field in the Documenso document editor](public/document-signing/number-field-document-editor-view.webp) +![The number field in the Documenso document editor](/document-signing/number-field-document-editor-view.webp) The number field settings include: @@ -221,7 +221,7 @@ In this example, the number field is configured as follows: - Validation: - Min value: 5, Max value: 50 -![A number field with the label configured by the user in the Documenso document editor](public/document-signing/number-field-label.webp) +![A number field with the label configured by the user in the Documenso document editor](/document-signing/number-field-label.webp) Since the field has a label set, the label is displayed instead of the default number field value - "Add number". @@ -231,23 +231,23 @@ What the recipient sees when they open the document to sign depends on the setti The recipient sees the number field signed with the default value in this case. -![Number field with the default value signed by the user in the Documenso document signing view](public/document-signing/number-field-autosigned.webp) +![Number field with the default value signed by the user in the Documenso document signing view](/document-signing/number-field-autosigned.webp) Since the number field is not read-only, the recipient can modify its value. To change the value, the recipient must click the field to un-sign it. Once it's unsigned, the field uses the label set by the sender. -![Unsigned number field in the Documenso document signing view](public/document-signing/number-field-unsigned.webp) +![Unsigned number field in the Documenso document signing view](/document-signing/number-field-unsigned.webp) To sign the field with a different value, the recipient needs to click on the field and enter the new value. -![Number field with the number input in the Documenso document signing view](public/document-signing/number-field-input-modal.webp) +![Number field with the number input in the Documenso document signing view](/document-signing/number-field-input-modal.webp) Since the number field has a validation rule set, the recipient must enter a value that meets the rules. In this example, the value needs to be between 5 and 50. Otherwise, an error message will appear, and the field will not be signed. The image below illustrates the text field signed with a new value. -![Number field signed with a new value](public/document-signing/number-field-signed-with-another-value.webp) +![Number field signed with a new value](/document-signing/number-field-signed-with-another-value.webp) After signing the field, the recipient can click the "Complete" button to complete the signing process. @@ -259,11 +259,11 @@ The radio field is used to collect a single choice from the signer. Place the radio field on the document where you want the signer to select a choice. The radio field comes with additional settings that can be configured. -![The radio field in the Documenso document editor](public/document-signing/radio-field-document-editor-view.webp) +![The radio field in the Documenso document editor](/document-signing/radio-field-document-editor-view.webp) To open the settings, click on the radio field and then on the "Sliders" icon. That opens the settings panel on the right side of the screen. -![The radio field advanced settings in the Documenso document editor](public/document-signing/radio-field-advanced-settings-document-editor-view.webp) +![The radio field advanced settings in the Documenso document editor](/document-signing/radio-field-advanced-settings-document-editor-view.webp) The radio field settings include: @@ -293,7 +293,7 @@ In this example, the radio field is configured as follows: - Empty value - Option 3 -![The radio field with the settings configured by the user in the Documenso document editor](public/document-signing/radio-field-options-document-editor-view.webp) +![The radio field with the settings configured by the user in the Documenso document editor](/document-signing/radio-field-options-document-editor-view.webp) Since the field contains radio options, it displays them instead of the default radio field value, "Radio". @@ -303,11 +303,11 @@ What the recipient sees when they open the document to sign depends on the setti In this case, the recipient sees the radio field unsigned because the sender didn't select a value. -![Radio field with no value selected in the Documenso document signing view](public/document-signing/radio-field-unsigned.webp) +![Radio field with no value selected in the Documenso document signing view](/document-signing/radio-field-unsigned.webp) The recipient can select one of the options by clicking on the radio button next to the option. -![Radio field with the value selected by the user in the Documenso document signing view](public/document-signing/radio-field-signed.webp) +![Radio field with the value selected by the user in the Documenso document signing view](/document-signing/radio-field-signed.webp) After signing the field, the recipient can click the "Complete" button to complete the signing process. @@ -319,11 +319,11 @@ The checkbox field is used to collect multiple choices from the signer. Place the checkbox field on the document where you want the signer to select choices. The checkbox field comes with additional settings that can be configured. -![The checkbox field in the Documenso document editor](public/document-signing/checkbox-document-editor-view.webp) +![The checkbox field in the Documenso document editor](/document-signing/checkbox-document-editor-view.webp) To open the settings, click on the checkbox field and then on the "Sliders" icon. That opens the settings panel on the right side of the screen. -![The checkbox field settings in the Documenso document editor](public/document-signing/checkbox-advanced-settings.webp) +![The checkbox field settings in the Documenso document editor](/document-signing/checkbox-advanced-settings.webp) The checkbox field settings include the following: @@ -356,7 +356,7 @@ In this example, the checkbox field is configured as follows: - Option 3 (checked) - Empty value -![The checkbox field with the settings configured by the user in the Documenso document editor](public/document-signing/checkbox-advanced-settings-document-editor-view.webp) +![The checkbox field with the settings configured by the user in the Documenso document editor](/document-signing/checkbox-advanced-settings-document-editor-view.webp) Since the field contains checkbox options, it displays them instead of the default checkbox field value, "Checkbox". @@ -366,7 +366,7 @@ What the recipient sees when they open the document to sign depends on the setti In this case, the recipient sees the checkbox field signed with the values selected by the sender. -![Checkbox field with the values selected by the user in the Documenso document signing view](public/document-signing/checkbox-field-document-signing-view.webp) +![Checkbox field with the values selected by the user in the Documenso document signing view](/document-signing/checkbox-field-document-signing-view.webp) Since the field is required, the recipient can either sign with the values selected by the sender or modify the values. @@ -377,11 +377,11 @@ The values can be modified in 2 ways: The image below illustrates the checkbox field with the values cleared by the recipient. Since the field is required, it has a red border instead of the yellow one (non-required fields). -![Checkbox field the values cleared by the user in the Documenso document signing view](public/document-signing/checkbox-field-unsigned.webp) +![Checkbox field the values cleared by the user in the Documenso document signing view](/document-signing/checkbox-field-unsigned.webp) Then, the recipient can select values other than the ones chosen by the sender. -![Checkbox field with the values selected by the user in the Documenso document signing view](public/document-signing/checkbox-field-custom-sign.webp) +![Checkbox field with the values selected by the user in the Documenso document signing view](/document-signing/checkbox-field-custom-sign.webp) After signing the field, the recipient can click the "Complete" button to complete the signing process. @@ -393,11 +393,11 @@ The dropdown/select field collects a single choice from a list of options. Place the dropdown/select field on the document where you want the signer to select a choice. The dropdown/select field comes with additional settings that can be configured. -![The dropdown/select field in the Documenso document editor](public/document-signing/select-field-sliders.webp) +![The dropdown/select field in the Documenso document editor](/document-signing/select-field-sliders.webp) To open the settings, click on the dropdown/select field and then on the "Sliders" icon. That opens the settings panel on the right side of the screen. -![The dropdown/select field settings in the Documenso document editor](public/document-signing/select-field-advanced-settings-panel.webp) +![The dropdown/select field settings in the Documenso document editor](/document-signing/select-field-advanced-settings-panel.webp) The dropdown/select field settings include: @@ -433,14 +433,14 @@ What the recipient sees when they open the document to sign depends on the setti In this case, the recipient sees the dropdown/select field with the default label, "-- Select ---" since the sender has not set a default value. -![Dropdown/select field in the Documenso document signing view](public/document-signing/select-field-unsigned.webp) +![Dropdown/select field in the Documenso document signing view](/document-signing/select-field-unsigned.webp) The recipient can modify the dropdown/select field value since the field is not read-only. To change the value, the recipient must click on the field for the dropdown list to appear. -![Dropdown/select field with the dropdown list in the Documenso document signing view](public/document-signing/select-field-unsigned-dropdown.webp) +![Dropdown/select field with the dropdown list in the Documenso document signing view](/document-signing/select-field-unsigned-dropdown.webp) The recipient can select one of the options from the list. The image below illustrates the dropdown/select field signed with a new value. -![Dropdown/select field signed with a value](public/document-signing/select-field-signed.webp) +![Dropdown/select field signed with a value](/document-signing/select-field-signed.webp) After signing the field, the recipient can click the "Complete" button to complete the signing process. diff --git a/apps/documentation/pages/users/signing-documents/index.mdx b/apps/documentation/pages/users/signing-documents/index.mdx index df43b5851..a0a32399d 100644 --- a/apps/documentation/pages/users/signing-documents/index.mdx +++ b/apps/documentation/pages/users/signing-documents/index.mdx @@ -18,17 +18,17 @@ The guide assumes you have a Documenso account. If you don't, you can create a f Navigate to the [Documenso dashboard](https://app.documenso.com/documents) and click on the "Add a document" button. Select the document you want to upload and wait for the upload to complete. -![Documenso dashboard](public/document-signing/documenso-documents-dashboard.webp) +![Documenso dashboard](/document-signing/documenso-documents-dashboard.webp) After the upload is complete, you will be redirected to the document's page. You can configure the document's settings and add recipients and fields here. -![Documenso document overview](public/document-signing/documenso-uploaded-document.webp) +![Documenso document overview](/document-signing/documenso-uploaded-document.webp) ### (Optional) Advanced Options Click on the "Advanced options" button to access additional settings for the document. You can set an external ID, date format, time zone, and the redirect URL. -![Advanced settings for a document uploaded in the Documenso dashboard](public/document-signing/documenso-uploaded-document-advanced-options.webp) +![Advanced settings for a document uploaded in the Documenso dashboard](/document-signing/documenso-uploaded-document-advanced-options.webp) The external ID allows you to set a custom ID for the document that can be used to identify the document in your external system(s). @@ -45,7 +45,7 @@ The available options are: - **Require account** - The recipient must be signed in to view the document. - **None** - The document can be accessed directly by the URL sent to the recipient. -![Document access settings in the Documenso dashboard](public/document-signing/documenso-enterprise-document-access.webp) +![Document access settings in the Documenso dashboard](/document-signing/documenso-enterprise-document-access.webp) The "Document Access" feature is only available for Enterprise accounts. @@ -61,7 +61,7 @@ The available options are: - **Require 2FA** - The recipient must have an account and 2FA enabled via their settings. - **None** - No authentication required. -![Document recipient action authentication in the Documenso dashboard](public/document-signing/document-enterprise-recipient-action-authentication.webp) +![Document recipient action authentication in the Documenso dashboard](/document-signing/document-enterprise-recipient-action-authentication.webp) This can be overridden by setting the authentication requirements directly for each recipient in the next step. @@ -75,11 +75,11 @@ Click the "+ Add Signer" button to add a new recipient. You can configure the re You can choose any option from the ["Recipient Authentication"](#optional-recipient-authentication) section, or you can set it to "Inherit authentication method" to use the global action signing authentication method configured in the "General Settings" step. -![The required authentication method for a recipient](public/document-signing/documenso-document-recipient-authentication-method.webp) +![The required authentication method for a recipient](/document-signing/documenso-document-recipient-authentication-method.webp) You can also set the recipient's role, which determines their actions and permissions in the document. -![The recipient role](public/document-signing/documenso-document-recipient-role.webp) +![The recipient role](/document-signing/documenso-document-recipient-role.webp) #### Roles @@ -96,7 +96,7 @@ Documenso has 4 roles for recipients with different permissions and actions. Documenso supports 9 different field types that can be added to the document. Each field type collects various information from the recipients when they sign the document. -![The available field types in the Documenso dashboard](public/document-signing/documenso-document-fields.webp) +![The available field types in the Documenso dashboard](/document-signing/documenso-document-fields.webp) The available field types are: @@ -121,13 +121,13 @@ All fields can be placed anywhere on the document and resized as needed. Signer Roles require at least 1 signature field. You will get an error message if you try to send a document without a signature field. -![Error message when trying to send a document without a signature field](public/document-signing/documenso-no-signature-field-found.webp) +![Error message when trying to send a document without a signature field](/document-signing/documenso-no-signature-field-found.webp) ### Email Settings Before sending the document, you can configure the email settings and customize the subject line, message, and sender name. -![Email settings in the Documenso dashboard](public/document-signing/documenso-document-email-settings.webp) +![Email settings in the Documenso dashboard](/document-signing/documenso-document-email-settings.webp) If you leave the email subject and message empty, Documenso will use the default email template. @@ -135,13 +135,13 @@ If you leave the email subject and message empty, Documenso will use the default After configuring the document, click the "Send" button to send the document to the recipients. The recipients will receive an email with a link to sign the document. -![The email sent to the recipients with the signing link](public/document-signing/documenso-sign-email.webp) +![The email sent to the recipients with the signing link](/document-signing/documenso-sign-email.webp) #### Signing Link If you need to copy the signing link for each recipient, you can do so by clicking on the recipient whose link you want to copy. The signing link is copied automatically to your clipboard. -![How to copy the signing link for each recipient from the Documenso dashboard](public/document-signing/documenso-signing-links.webp) +![How to copy the signing link for each recipient from the Documenso dashboard](/document-signing/documenso-signing-links.webp) The signing link has the following format: diff --git a/apps/documentation/pages/users/templates.mdx b/apps/documentation/pages/users/templates.mdx index ba7fc7fd8..aa3c86798 100644 --- a/apps/documentation/pages/users/templates.mdx +++ b/apps/documentation/pages/users/templates.mdx @@ -10,15 +10,15 @@ Documenso allows you to create templates, which are reusable documents. Template To create a new template, navigate to the ["Templates" page](https://app.documenso.com/templates) and click on the "New Template" button. -![Documenso template page](public/templates/documenso-template-page.webp) +![Documenso template page](/templates/documenso-template-page.webp) Clicking on the "New Template" button opens a new modal to upload the document you want to use as a template. Select the document and wait for Documenso to upload it to your account. -![Upload a new template document in the Documenso dashboard](public/templates/documenso-template-page-upload-document.webp) +![Upload a new template document in the Documenso dashboard](/templates/documenso-template-page-upload-document.webp) Once the upload is complete, Documenso opens the template configuration page. -![A successfuly uploaded document in the Documenso dashboard](public/templates/documenso-template-page-uploaded-document.webp) +![A successfuly uploaded document in the Documenso dashboard](/templates/documenso-template-page-uploaded-document.webp) You can then configure the template by adding recipients, fields, and other options. @@ -28,7 +28,7 @@ When you send a document for signing, Documenso emails the recipients with a lin Documenso uses a generic subject and message but also allows you to customize them for each document and template. -![Configuring the email options for the Documenso template](public/templates/documenso-template-page-uploaded-document-email-options.webp) +![Configuring the email options for the Documenso template](/templates/documenso-template-page-uploaded-document-email-options.webp) To configure the email options, click the "Email Options" tab and fill in the subject and message fields. Every time you use this template for signing, Documenso will use the custom subject and message you provided. They can also be overridden before sending the document. @@ -36,7 +36,7 @@ To configure the email options, click the "Email Options" tab and fill in the su The template also has advanced options that you can configure. These options include settings such as the external ID, date format, time zone and the redirect URL. -![Configuring the advanced options for the Documenso template](public/templates/documenso-template-page-uploaded-document-advanced-options.webp) +![Configuring the advanced options for the Documenso template](/templates/documenso-template-page-uploaded-document-advanced-options.webp) The external ID allows you to set a custom ID for the document that can be used to identify the document in your external system(s). @@ -50,7 +50,7 @@ You can add placeholders for the template recipients. Placeholders specify where You can also add recipients directly to the template. Recipients are the people who will receive the document for signing. -![Adding placeholder recipients for the Documenso template](public/templates/documenso-template-recipients.webp) +![Adding placeholder recipients for the Documenso template](/templates/documenso-template-recipients.webp) If you add placeholders to the template, you must replace them with actual recipients when creating a document from it. See the modal from the ["Use a Template"](#use-a-template) section. @@ -70,7 +70,7 @@ Documenso provides the following field types: - **Checkbox** - Collects multiple choices from the signer - **Dropdown/Select** - Collects a single choice from a list of choices -![Adding fields for the Documenso template](public/templates/documenso-template-page-fields.webp) +![Adding fields for the Documenso template](/templates/documenso-template-page-fields.webp) After adding the fields, press the "Save Template" button to save the template. @@ -85,7 +85,7 @@ Click on the "Use Template" button to create a new document from the template. B After filling in the recipients, click the "Create Document" button to create the document in your account. -![Use an available Documenso template](public/templates/documenso-use-template.webp) +![Use an available Documenso template](/templates/documenso-use-template.webp) You can also send the document straight to the recipients for signing by checking the "Send document" checkbox. diff --git a/apps/documentation/public/embedding/copy-recipient-token.png b/apps/documentation/public/embedding/copy-recipient-token.png new file mode 100644 index 000000000..fde239b83 Binary files /dev/null and b/apps/documentation/public/embedding/copy-recipient-token.png differ diff --git a/apps/documentation/public/embedding/enable-direct-link.png b/apps/documentation/public/embedding/enable-direct-link.png new file mode 100644 index 000000000..871a1c94d Binary files /dev/null and b/apps/documentation/public/embedding/enable-direct-link.png differ diff --git a/apps/documentation/public/embedding/team-templates.png b/apps/documentation/public/embedding/team-templates.png new file mode 100644 index 000000000..e052ecf2d Binary files /dev/null and b/apps/documentation/public/embedding/team-templates.png differ diff --git a/apps/marketing/content/blog/introducing-embedding.mdx b/apps/marketing/content/blog/introducing-embedding.mdx new file mode 100644 index 000000000..45a04aec2 --- /dev/null +++ b/apps/marketing/content/blog/introducing-embedding.mdx @@ -0,0 +1,72 @@ +--- +title: 'Introducing Embedding Support for Documenso' +description: 'Embedding is now here! Learn how we built it and how it can be used to bring e-signing to your own applications.' +authorName: 'Lucas Smith' +authorImage: '/blog/blog-author-lucas.png' +authorRole: 'Co-Founder' +date: 2024-09-06 +tags: + - Development +--- + +When we first launched Documenso, one of the most requested features was embedding. We knew it was important and aligned with our desire to not just be a e-signing application but to instead provide the e-signature infrastructure for the web and beyond. + +With that said, we decided to hold off initially so we could focus on building a solid, well-featured core application. Looking back, this was definitely the right call. Embedding is only as good as the features behind it, and we didn't want to release something that wasn't ready to meet user and developer expectations. + +Over the past year, we've been busy adding tons of new features and reaching new levels of compliance, like 21 CFR Part 11. We've also introduced [new fields](/blog/introducing-advanced-signing-fields), [built out an API](/blog/public-api), [added webhooks, integrations with Zapier](/blog/launch-week-2-day-4), and a lot more. + +Now that we've laid a solid foundation, it's finally time to focus on embedding, the top-requested feature from both our users and those self-hosting our platform. + +## Why Embedding Took Time + +In previous projects, I’ve often seen embedding built by bundling components for use in a client’s website or app. This method gives users maximum flexibility for styling and behavior, while avoiding certain cross-origin issues. However, it can also introduce problems like code conflicts or performance bottlenecks. For example, third-party tools such as Google Tag Manager (GTM) or other marketing scripts can interfere with your SDK. Additionally, the SDK must remain lightweight to avoid slowing down the client’s page. + +For Documenso, we decided to explore a different approach. After carefully researching our options, we opted for an iframe-based solution. While iframes are typically less flexible—especially when it comes to theming or passing pre-filled data containing personally identifiable information (PII)—we identified ways to mitigate these concerns. + +One of the biggest challenges was ensuring that we could pass sensitive data, like emails for pre-filling forms, without exposing PII to our server. To solve this, we used [fragment identifiers](https://developer.mozilla.org/en-US/docs/Web/API/URL/hash) in the URL, which are processed client-side and never sent in network requests. This method ensures that PII is protected and not logged by our server or any intermediate web services. + +### Using the PostMessage API for Communication + +To maintain a high level of interactivity, our iframes communicate with the parent window using the [postMessage API](https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage). This allows us to notify the parent app when specific events occur inside the iframe, creating a more dynamic user experience and bridging the gap between our iframe-based solution and typical fat SDKs. + +Additionally, props are passed into the iframe via the [fragment identifier](https://developer.mozilla.org/en-US/docs/Web/API/URL/hash) of the URL. This avoids the need for complex two-way data synchronization between the parent and child frames, making the system stable and more reliable. + +### Building the Embeds with Mitosis + +Given that our iframe solution is quite lightweight, we saw this as a great opportunity to experiment with [Mitosis](https://mitosis.builder.io/) which would let us do something truly special. For those unfamiliar, Mitosis is a project by Builder.io that lets you write components once and then transpile them into a variety of frameworks like React, Vue, and Svelte. + +We used Mitosis to build two key components: a direct template embed and a document signing embed. The direct template allows users to use a template as if it were an evergreen document—meaning that, when someone completes the template, a new document is automatically generated. This is the use case we expect most users to adopt for embedding. For more advanced workflows, we also offer a document signing embed, which can handle multi-recipient workflows and other complex scenarios intended for use in deeper, rich integrations. + +Mitosis allowed us to quickly target several popular frameworks, including [React](https://www.npmjs.com/package/@documenso/embed-react), [Preact](https://www.npmjs.com/package/@documenso/embed-preact), [Vue](https://www.npmjs.com/package/@documenso/embed-vue), [Svelte](https://www.npmjs.com/package/@documenso/embed-svelte), and [SolidJS](https://www.npmjs.com/package/@documenso/embed-solid). + +I had also hoped to include Angular, but while Mitosis makes it really easy to transpile component, we still have to take care of bundling and packaging the resulting component ourselves. While the above frameworks can all be bundled using Vite.js, Angular still has it's own set of tooling that we would need to learn and use. Given this constraint we opted to put Angular on hold for now while we wait for the newer Vite.js support to mature. + +### Challenges and Lessons with Mitosis and more + +While our experience with Mitosis was largely positive, there were some challenges along the way. For instance, certain state properties with the same names as props caused issues during the transpilation process, leading to type errors and unexpected transpilation results with some targets. + +This was also a challenge since our initial implementation of the two components had some minor separation of concerns which also resulted in some transpilation issues with some targets. We addressed this by removing the separation of concerns for now since it was mostly for show rather than out of necessity. + +On top of that, packaging and publishing the embeds posed its own set of challenges, particularly given the growing complexity of JavaScript package management. Tools like [Publint](https://www.npmjs.com/package/publint) helped streamline the process by ensuring we followed best practices for both CommonJS and ESM formats. + +### To the Future, The Documenso Platform + +With the embedding feature now in place, we're excited to continue expanding Documenso's capabilities. Embeds are just the beginning of what we're calling the Documenso platform. Through our user research, we've learned that while many businesses appreciate having a flexible e-signature solution, they're even more interested in using our tools to build signing functionality directly into their own apps—without worrying about the technical complexities of compliance and security that come with e-signing. + +Over the coming months, we'll be working on enhancing our API, strengthening integrations with tools like Zapier, and improving our webhook system. Our goal is to give users the ability to embed e-signatures and document management wherever they need it, whether that's through self-hosting or by using Documenso as a platform. We can't wait to see how our users and self-hosters leverage these new capabilities! + +### Ready to Get Started? + +If you're ready to embed document signing into your own app or website, check out our [Embedding Documentation](https://docs.documenso.com/developers/embedding?utm_source=blog&utm_campaign=introducing-embedding) to see how easy it is to get started. You'll find everything you need to get started today! + +