Skip to main content
Embedding v2 is in beta. Embed sessions and SDK 1.0 can change in ways that break your integration before the first stable release, estimated for November 2026. Embedding v1, described in Embedded signing, is stable.
In this guide, you embed the sajn signing page in a React app with the SigningEmbed component from @sajn/embed-react. The component wraps createSigningEmbed from @sajn/embed-js.

Before you begin

  • Turn on embedding for your organization and add your domain to the embed domains. For more information, see Add your embed domains.
  • Create and send the document, and note the party’s id. For the steps, see Embed the signing page.
  • React 18 or 19.

Install the package

Create a session on your server

Your React code never calls the sajn API. Add a server endpoint that creates an embed session and returns its clientSecret. In the Next.js App Router, use a route handler:
The component calls this endpoint again each time a session ends, so create a new session on every call. For every field of the request, see Create session request.

Show the signing page

Render SigningEmbed with a fetchClientSecret function. The component is a client component, marked with "use client":
The component renders a div that holds the frame. className and style apply to that div, so give it a height there.

Props

The callback props are onReady, onSigned, onRejected, onFieldsSubmitted, onVerified, onStateChange, onResize, onSessionExpired, and onError. For when each one runs and its data, see Events.

Show a document read-only

Create the session with type: "viewing" and render ViewingEmbed. It takes the same props as SigningEmbed. The frame shows the document with no sign section.

Update the frame

The component reads fetchClientSecret and the callbacks from the latest render, so inline functions are fine and never reload the frame.
  • A change to appearance or locale updates the open frame without reloading it.
  • A change to host, title, or fallbackHeight creates a new frame and a new session.
For example, to follow a theme toggle in your app:
Features can’t change from the browser. To change them, create a new session.
In development, React Strict Mode mounts the component twice, so your endpoint gets two requests and creates two sessions. The first session expires unused. Production builds mount once.

TypeScript types

The package exports its types:

Troubleshooting

  • onError gets bootstrap_timeout, and the frame is blank: the browser most likely refused the frame. Check the session’s origins against the page’s exact origin, and your page’s own frame-src policy. In Next.js, a Content-Security-Policy set in next.config or middleware must allow https://app.sajn.se in frame-src. For every cause, see Fix a blank frame.
  • onError gets client_secret_failed: fetchClientSecret threw an error, or returned something other than the clientSecret string.
  • The frame is 600px high and doesn’t fill the container: the container has no height. Set one with className or style.
For the other error codes, see Error codes.

Next steps

Embedded signing

See the session request, the appearance, the events, and the error codes.

Embed signing in your app

Run the whole flow from server to frame.