@dadan-io/record-sdk-vue adds Dadan recording to a Vue 3 app. It gives you a record button component, composables for your own button, and a wrapper for the <dadan-recorder> web component. It supports Vue 3.3 and later, including Nuxt.
Before you start, read the Record SDK overview and get a public app ID with your development origin allowlisted.
Install the package
Link to section: Install the packagenpm install @dadan-io/record-sdk-vue react@^18 react-dom@^18The recording studio is built with React, so it needs react and react-dom even though you will not write any React code. npm 7 and later install them automatically but choose React 19 unless you pin a version. React 18 is smaller and is the version the studio is tested with. Yarn and pnpm (without auto-install-peers) do not install them, so keep them in the command.
Two setup notes:
- TypeScript. Use
"moduleResolution": "bundler"(the Vite default),"node16"or"nodenext". If yourtsconfig.jsonsets"skipLibCheck": false, also runnpm install -D @types/react. - Vite warning. Vite may print one warning about a
"use client"directive in the package. It is harmless: the directive is there for Next.js and Vue ignores it.
Add the record button
Link to section: Add the record button<script setup lang="ts">
import {
DadanRecordButton,
type CreateInstanceArgs,
type DadanVideo,
} from "@dadan-io/record-sdk-vue";
const sdk: CreateInstanceArgs = {
mode: "custom",
publicAppId: import.meta.env.VITE_DADAN_PUBLIC_APP_ID,
videoTitle: "Customer feedback",
folderId: "123456",
};
function onInsert(video: DadanVideo) {
console.info("Uploaded", video.id, video.sharedUrl);
}
function onError(error: { message?: string }) {
console.error("Recording failed", error.message);
}
</script>
<template>
<DadanRecordButton
:sdk="sdk"
label="Record feedback"
@insert="onInsert"
@error="onError"
/>
</template>DadanRecordButton renders the Dadan record button and opens the built-in studio on click. It emits:
| Event | When |
|---|---|
insert | The upload finished and the studio closed. The payload is a DadanVideo |
cancel | The person closed the studio without uploading |
error | Something failed. The payload has a code and a message |
The button is disabled in browsers that cannot record. Changing values in sdk rebuilds the studio, but only while it is closed, so a take in progress is never lost.
Use your own button
Link to section: Use your own buttonWith useDadanRecorder
Link to section: With useDadanRecorder<script setup lang="ts">
import {
useDadanRecorder,
type CreateInstanceArgs,
} from "@dadan-io/record-sdk-vue";
const sdk: CreateInstanceArgs = {
mode: "custom",
publicAppId: import.meta.env.VITE_DADAN_PUBLIC_APP_ID,
};
const { ready, supported, lastVideo, open } = useDadanRecorder(sdk);
</script>
<template>
<p v-if="!supported">Video recording is not available in this browser.</p>
<button v-else type="button" class="btn" :disabled="!ready" @click="open">
Record a video
</button>
<a v-if="lastVideo" :href="lastVideo.sharedUrl">Watch your recording</a>
</template>useDadanRecorder returns refs: ready, supported, supportError, error, lastVideo and instance, plus open() and close(). The studio is torn down automatically when the component unmounts.
With useDadanRecordButton
Link to section: With useDadanRecordButtonIf you already have a button element, useDadanRecordButton wires it to the studio for you:
<script setup lang="ts">
import { ref } from "vue";
import {
useDadanRecordButton,
type DadanVideo,
} from "@dadan-io/record-sdk-vue";
const button = ref<HTMLButtonElement | null>(null);
const recorded = ref<DadanVideo | null>(null);
useDadanRecordButton(
button,
{ mode: "custom", publicAppId: import.meta.env.VITE_DADAN_PUBLIC_APP_ID },
(video) => (recorded.value = video),
);
</script>
<template>
<button ref="button" type="button">Record</button>
<p v-if="recorded">Uploaded: {{ recorded.title ?? recorded.id }}</p>
</template>React to studio events
Link to section: React to studio eventsFor progress bars or analytics, subscribe to the studio’s events through instance once it is ready:
<script setup lang="ts">
import { ref, watch } from "vue";
import { useDadanRecorder } from "@dadan-io/record-sdk-vue";
const percent = ref<number | null>(null);
const { instance, open, ready } = useDadanRecorder({
mode: "custom",
publicAppId: import.meta.env.VITE_DADAN_PUBLIC_APP_ID,
});
watch(instance, (studio, _old, onCleanup) => {
if (!studio) return;
const off = studio.contractEmitter.on(
"upload.progress",
(p) => (percent.value = p.percent),
);
onCleanup(off);
});
</script>
<template>
<button type="button" :disabled="!ready" @click="open">Record</button>
<progress v-if="percent !== null" :value="percent" max="100">
{{ percent }}%
</progress>
</template>Use the web component wrapper
Link to section: Use the web component wrapperDadanRecorderHost wraps <dadan-recorder>. It suits pages where the studio should open on its own, for example a dedicated “record your answer” page:
<script setup lang="ts">
import {
DadanRecorderHost,
type DadanVideo,
} from "@dadan-io/record-sdk-vue";
const appId = import.meta.env.VITE_DADAN_PUBLIC_APP_ID;
function onInsert(video: DadanVideo) {
console.info(video.sharedUrl);
}
</script>
<template>
<DadanRecorderHost
:public-app-id="appId"
video-title="Interview answer"
auto-open
@insert="onInsert"
/>
</template>Its props are publicAppId, uploadToken, jws, styleNonce, videoTitle, folderId, teamId, mode and autoOpen. It emits insert, uploadComplete, backdropChange, cancel and error. Tokens are set on the element as properties, never as HTML attributes.
The recorder needs browser APIs, so render it on the client only. Either wrap it:
<template>
<ClientOnly>
<RecordFeedback />
</ClientOnly>
</template>or name the component file with a .client.vue suffix, for example components/RecordFeedback.client.vue. Expose the public app ID through runtimeConfig.public in nuxt.config.ts.
Custom recorder screens
Link to section: Custom recorder screensTo build every screen yourself, use DadanRecorder, which this package re-exports from @dadan-io/record-sdk. Create it in onMounted, call destroy() in onBeforeUnmount, and follow Build a custom recorder with DadanRecorder.