Record SDK for Vue

On this page
  1. Install the package
  2. Add the record button
  3. Use your own button
  4. React to studio events
  5. Use the web component wrapper
  6. Nuxt
  7. Custom recorder screens
  8. Next steps

@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.

bash
npm install @dadan-io/record-sdk-vue react@^18 react-dom@^18

The 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 your tsconfig.json sets "skipLibCheck": false, also run npm 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.
vue
<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:

EventWhen
insertThe upload finished and the studio closed. The payload is a DadanVideo
cancelThe person closed the studio without uploading
errorSomething 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.

vue
<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.

If you already have a button element, useDadanRecordButton wires it to the studio for you:

vue
<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>

For progress bars or analytics, subscribe to the studio’s events through instance once it is ready:

vue
<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>

DadanRecorderHost wraps <dadan-recorder>. It suits pages where the studio should open on its own, for example a dedicated “record your answer” page:

vue
<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:

vue
<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.

To 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.

Ask AI about this article

What should the AI help you with?

Are you still facing issues?

Reach out to our support team for further assistance.

dadan