@dropby/vue
| Install | |
|---|---|
npm install @dropby/vue |
|
| Latest Version: | 0.5.0 |
| Vue: | 3 |
| License: | MIT |
| Last Updated: | Sep 29, 2026 |
| Links: | npm |
@dropby/vue
DropBy for Vue 3: a provider, composables for support chat, ideas, pending asks and feature flags, and optional unstyled components. It supports Vue 3.4 and later 3.x releases.
Installation
pnpm add @dropby/vue @dropby/browser
@dropby/browser holds the options and data types, and its README explains
sessions, context and flags in full. Keep the two packages on the same version;
every release publishes them together.
Provider and composables
With options, DropByProvider creates the DropBy instance, starts it once
mounted, and destroys it with its scope. Your auth callback calls your own
backend, which knows who is signed in and creates the session; see
@dropby/server.
<script setup lang="ts">
import { onMounted, ref } from "vue";
import type { DropByOptions } from "@dropby/browser";
import { DropByProvider } from "@dropby/vue";
import Inbox from "./Inbox.vue";
const options: DropByOptions = {
publicKey: "YOUR_PUBLIC_KEY",
auth: async ({ refresh }) => {
const response = await fetch("/api/dropby/session", {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify({ refresh }),
});
if (!response.ok) throw new Error("could not create a DropBy session");
return response.json();
},
};
const mounted = ref(false);
onMounted(() => {
mounted.value = true;
});
</script>
<template>
<DropByProvider v-if="mounted" :options="options">
<Inbox />
</DropByProvider>
</template>
Inbox.vue lists the unread conversations. useChatThread(id) and
useFeatureFlag(name) also take a ref or a getter, and follow it when it
changes.
<script setup lang="ts">
import { onMounted } from "vue";
import { useChatThreads } from "@dropby/vue";
const { data, actions } = useChatThreads();
onMounted(() => void actions.listThreads({ filter: "unread" }));
</script>
<template>
<p>{{ data.items.length }} unread threads</p>
</template>
useChatThreads,useChatThread(id),useChatUnread,useIdeasandusePendingAsksreturndataas a read-only ref and a stableactionsobject.useDropBy()returns the instance.useDropByState()returns its livebootstrap,capabilitiesandconnectionrefs.- An instance passed as the provider's
dropbyprop stays yours to start and destroy. - The
v-ifabove mounts DropBy only in the browser. Never share an instance across server requests. - The provider reads
optionsonce. When a user logs out, or another user or account signs in, mount a new provider (give it a:keyof the user's and account's ids) so the old instance is destroyed. - Use the full
pk_live_...orpk_test_...value from the dashboard's API keys page forYOUR_PUBLIC_KEY.
Feature flags
useFeatureFlag(name) returns one flag's value as a ref, and useFeatureConfig()
all of them. <Feature> renders its default slot when a flag is on (truthy, or
equal to equals), and its fallback slot otherwise. Before the instance
starts, and for a flag that does not exist, the value is undefined. How flags
are resolved, and when they change, is in the
@dropby/browser README.
<script setup lang="ts">
import { useFeatureFlag } from "@dropby/vue";
import { Feature } from "@dropby/vue/components";
const format = useFeatureFlag("export_format");
</script>
<template>
<Feature name="new_exports">
<button type="button">export as {{ format === "csv" ? "csv" : "pdf" }}</button>
<template #fallback><span>exports are coming soon</span></template>
</Feature>
</template>
Components and styling
Optional components live in @dropby/vue/components: ChatThread,
ChatThreadList, ChatComposer, IdeaList, Idea, IdeaVoteButton, Ask,
AskForm, PendingAsks and Feature. They render plain, accessible HTML with
state attributes such as data-status, data-unread and data-busy, so your
own CSS styles them; they load no theme. Each, except Feature, also takes a
default scoped slot when you want your own markup with its state, and the slot
props are typed:
<script setup lang="ts">
import { ChatThreadList } from "@dropby/vue/components";
const emit = defineEmits<{ open: [threadId: `thr_${string}`] }>();
</script>
<template>
<ChatThreadList v-slot="{ threads }">
<button
v-for="thread in threads.items"
:key="thread.threadId"
type="button"
@click="emit('open', thread.threadId)"
>
{{ thread.lastMessagePreview }}
</button>
<p v-if="threads.status === 'error'">couldn't load your conversations.</p>
</ChatThreadList>
</template>
The default chat components behave like the hosted widget:
ChatThreadmarks a reply seen once its end is on screen (the page visible, the viewer allowed). Pass:acknowledge="false"to do that yourself withactions.markSeen. A slot body is never observed.ChatThreadfollows new messages inside its own scroll container: to the newest when it opens, when the reader sends, and when a message arrives while they are at the end. It scrolls only its own scroll container (itself or the nearest ancestor withoverflow-y: auto), never the document.ChatThreadListrows become buttons with@select="(threadId) => ...";selected-idmarks the open one witharia-current.- Failed loads, sends and downloads show as
role="alert"messages in plain words. A slot's state carries theDropByErrorbehind a failed load or send. ChatComposerkeeps a failed message in the box. Sending it again unchanged cannot post it twice.
Optional attachments
Import useChatAttachments only when the composer needs uploads, so other
pages never load the upload code:
<script setup lang="ts">
import { ChatComposer } from "@dropby/vue/components";
import { useChatAttachments } from "@dropby/vue/components/chat-attachments";
defineProps<{ threadId: `thr_${string}` }>();
const attachments = useChatAttachments();
</script>
<template>
<ChatComposer :thread-id="threadId" :attachments="attachments" />
</template>
The composable returns drafts, add, remove, clear, references,
pending, notice and accept. ChatComposer waits for uploads in progress
and sends only the ready ones. Disposing the component's scope releases the
composable's previews and subscriptions; destroying the instance cancels its
uploads.
Related Packages
Version History
| Version | Released | Vue | License |
|---|---|---|---|
| 0.5.0 | ^3.4 | MIT | |
| 0.4.1 | ^3.4 | MIT | |
| 0.4.0 | ^3.4 | MIT |