Embed

Embed WeTransform directly into your JavaScript, React, or Vue 3 application using the official SDK packages.

@wetransform/core

Headless browser SDK. Open WeTransform as a modal or inline widget, authenticate users, and listen to typed events β€” framework-agnostic.

@wetransform/react

React wrapper around @wetransform/core. Provides a renderless component and a useWeTransform() hook.

@wetransform/vue

Vue 3 wrapper around @wetransform/core. Provides a renderless component and a useWeTransform() composable.

Installation

Vanilla JS / any framework
npm install @wetransform/core

πŸ“¦ @wetransform/core on npm

React
npm install @wetransform/react

react >= 18 is a peer dependency provided by your application.

πŸ“¦ @wetransform/react on npm

Vue 3
npm install @wetransform/vue

@wetransform/core is a peer dependency and will be installed automatically.

πŸ“¦ @wetransform/vue on npm

Configuration

Both packages share the same configuration object. Two values require setup in your WeTransform account.

  1. Organization handle (organizationHandle): The URL slug for your branded page (e.g. your-company for your-company.send-a-file.io). Set it in Integrations β†’ Embed
  2. Signature (authentication.signature): An HMAC-SHA256 token generated server-side to authenticate each user session.
Signature β€” server-side generation

Use your embed secret key (from Integrations β†’ Embed) to compute an HMAC-SHA256 over a payload, then pass the result as authentication.signature. The payload is the customer ID, optionally followed by the context you want to scope the session to, joined with a colon (:) in the fixed order customerId:templateHandle:sourceId. Include only the parts you need β€” append more only to narrow the scope.

// Customer only β€” full access for that customer
Signature = HMAC_SHA256("1234", "secret_key")

// Customer + template β€” scoped to a single template
Signature = HMAC_SHA256("1234:template-test", "secret_key")

// Customer + template + source β€” scoped to a single transformation
Signature = HMAC_SHA256("1234:template-test:550e8400-e29b-41d4-a716-446655440000", "secret_key")

Never expose the secret key to the browser. Generate the signature in your backend and pass it to the frontend.

The payload must contain exactly the context you pass in the config. If you provide a templateHandle, you must sign it as part of the payload; likewise for sourceId. A signature whose payload does not match the parameters sent to the SDK will be rejected.
Configuration reference
Option Type Required Description
organizationHandle string yes Your organization's URL slug (e.g. your-company)
authentication.customerId string yes Unique identifier for the current user in your system
authentication.signature string yes HMAC-SHA256 signature generated server-side
authentication.templateHandle string no Template handle for the current session
authentication.sourceId string no Source identifier for the current session
locale 'en' | 'fr' no UI language. Defaults to 'en'
displayAsModal boolean no Open as a centered modal overlay. Defaults to true
initialLocation string no Starting page inside WeTransform. When omitted, it is inferred from the authentication context β€” see Initial location for all values and the inference rules
mountElement string | HTMLElement no Custom container for inline (non-modal) mounting β€” element ID or element reference
customization.colors.primary string no Primary brand color (CSS color, e.g. #1a73e8). See Customization.
customization.colors.secondary string no Secondary brand color (CSS color)
Initial location

initialLocation chooses which screen opens first. Each location requires a matching authentication context, and that context must be part of the signed payload (see the signature note above).

Location What opens Required authentication Auto-selected when
transformations The customer's list of transformations customerId + signature No templateHandle and no sourceId
uploader File upload screen for a template + templateHandle templateHandle set, sourceId not set
finalize Final review / submit screen for a transformation + templateHandle + sourceId Both templateHandle and sourceId set
mapper Column mapping + templateHandle + sourceId explicit only
sourcePreview Read-only preview of the source file + templateHandle + sourceId explicit only
sourceUpdate Update an existing source + templateHandle + sourceId explicit only
loadSource Import a source + templateHandle + sourceId explicit only
scheduler Schedule a transformation + templateHandle + sourceId explicit only
When initialLocation is omitted, the SDK infers only transformations, uploader, or finalize from the authentication fields you pass. Every other location must be set explicitly, and it requires the templateHandle / sourceId shown above (enforced at the TypeScript type level).
Customization

Pass a customization object to apply your brand colors to the WeTransform UI.

customization: {
  colors: {
    primary: '#1a73e8',   // main brand color
    secondary: '#34a853', // accent color
  },
}

@wetransform/core

Use this package directly in any JavaScript or TypeScript project.

Basic usage
import { createWeTransform } from '@wetransform/core'

const sdk = createWeTransform({
  organizationHandle: 'your-org',
  locale: 'en',
  displayAsModal: true,
  authentication: {
    customerId: 'customer_id',
    signature: signatureGeneratedServerSide,
  },
  customization: {
    colors: { primary: '#1a73e8', secondary: '#34a853' },
  },
})

// Listen to events
sdk.on('successSubmit', ({ fileUrl, templateHandle, customerId, signature, userFileName }) => {
  console.log('File ready:', fileUrl)
})

// Open the WeTransform UI
await sdk.open()

// Update the locale at runtime
await sdk.setLocale('fr')

// Close the UI
await sdk.close()

// Clean up when done
await sdk.destroy()
Instance methods
Method Description
open() Initializes authentication and mounts the WeTransform UI. Returns Promise<void>
close() Closes the UI and unmounts the iframe. Returns Promise<void>
destroy() Closes and tears down all SDK resources. Returns Promise<void>
setLocale(locale) Switches the UI language ('en' or 'fr') at runtime. Returns Promise<void>
on(event, handler) Subscribes to an SDK event. Returns an unsubscribe function

If an event listener throws, the SDK isolates the exception and emits an error event with code listener_error.

@wetransform/react

Two integration styles are available. Choose the component for declarative UI state, or the hook when you need direct control over the SDK instance.

1. Renderless component

Drop <WeTransformSdk> into your component tree. Control visibility with open / onOpenChange, pass a reactive locale prop, and listen to SDK events with callback props.

Component usage
import { useState } from 'react'
import {
    WeTransformSdk,
    type WeTransformConfig,
    type WeTransformSdkProps,
    type SupportedLocales,
} from '@wetransform/react'

const config: WeTransformConfig = {
    organizationHandle: 'your-org',
    authentication: {
        customerId: 'customer_id',
        signature: signatureGeneratedServerSide,
    },
}

const onSuccessSubmit: WeTransformSdkProps['onSuccessSubmit'] = ({ fileUrl }) => {
    console.log('File ready:', fileUrl)
}

export function UploadButton() {
    const [isSdkOpen, setIsSdkOpen] = useState(false)
    const [locale, setLocale] = useState<SupportedLocales>('en')

    return (
        <>
            <button onClick={() => setIsSdkOpen(true)}>Open WeTransform</button>

            <WeTransformSdk
                config={config}
                open={isSdkOpen}
                onOpenChange={setIsSdkOpen}
                locale={locale}
                onSuccessSubmit={onSuccessSubmit}
                onError={console.error}
            />
        </>
    )
}
The component renders only its internal mount container, accepts no children, and forces mountElement internally. Use className and style to style that container. Live structural config changes are not applied automatically; destroy and open again, or remount with a React key.

2. Hook

Use useWeTransform() for direct control. Subscribe in an effect and return the unsubscribe function from on(...).

Hook usage
import { useEffect } from 'react'
import { useWeTransform, type WeTransformConfig } from '@wetransform/react'

const config: WeTransformConfig = {
    organizationHandle: 'your-org',
    authentication: {
        customerId: 'customer_id',
        signature: signatureGeneratedServerSide,
    },
}

export function UploadButton() {
    const { open, close, destroy, setLocale, isOpen, weTransformInstance, on } = useWeTransform(config)

    useEffect(() => {
        return on('successSubmit', ({ fileUrl }) => {
            console.log('File ready:', fileUrl)
        })
    }, [on])

    return <button onClick={() => open()}>Open WeTransform</button>
}

Live config changes are not applied automatically. Apply new structural config by destroying and opening again, or by remounting the hook owner with a React key.

@wetransform/vue

Two integration styles are available. Choose the one that fits your component structure.

1. Renderless component

Drop <WeTransformSdk> into your template. Use v-model:open to control visibility and listen to events with @successSubmit / @error.

Component usage
<script setup>
import { ref } from 'vue'
import { WeTransformSdk } from '@wetransform/vue'

const isOpen = ref(false)
const locale = ref('en')

const config = {
  organizationHandle: 'your-org',
  authentication: {
    customerId: 'customer_id',
    signature: signatureGeneratedServerSide,
  },
}

function onSuccess({ fileUrl, templateHandle, userFileName }) {
  console.log('File ready:', fileUrl)
}
</script>

<template>
  <button @click="isOpen = true">Open WeTransform</button>

  <WeTransformSdk
    v-model:open="isOpen"
    :config="config"
    :locale="locale"
    @successSubmit="onSuccess"
    @error="console.error"
  />
</template>
Do not pass mountElement or locale in the config when using the component β€” pass locale as a prop (it is reactive) and mounting is managed internally. For other structural config changes, remount using Vue's :key attribute.

2. Composable

Use useWeTransform() for more granular control. It accepts a plain config object, a Ref<WeTransformConfig>, or a getter function. The config is read when an SDK instance is created; live instances do not react to config changes.

Composable usage
import { useWeTransform } from '@wetransform/vue'

const config = () => ({
  organizationHandle: 'your-org',
  authentication: {
    customerId: customerId.value,
    signature: signature.value,
  },
})

const { open, close, destroy, setLocale, isOpen, weTransformInstance, on } = useWeTransform(config)

// Subscribe to events directly via the composable
on('successSubmit', ({ fileUrl }) => {
  console.log('File ready:', fileUrl)
})

When the structural config changes, create a new SDK instance by destroying and opening again, or remounting the component that owns the composable.

Events

The SDK emits the following events. Subscribe with sdk.on(event, handler) in @wetransform/core, via callback props or the hook in @wetransform/react, or via component event bindings in @wetransform/vue.

Event Description Payload
open Fired when the UI opens β€”
close Fired when the UI closes β€”
ready Fired when the iframe has fully loaded β€”
successSubmit Fired when a file has been processed successfully { customerId, templateHandle, fileUrl, signature, userFileName }
error Fired when an error occurs { code, message, stack? }
destroy Fired when the SDK instance is destroyed β€”
Verify successSubmit: The signature in the payload is signed by WeTransform. Always verify it server-side before processing the file β€” use the same HMAC-SHA256 check as the Redirect inbound verification.

Ready to go?

Configure your organization handle and signature secret to start using the SDK.

Configuration dashboard
© 2026