Framework Recipes
This page shows repeatable patterns that map to the same embed API across frameworks.
Recipe: open and close the widget
Section titled “Recipe: open and close the widget”Vanilla JS
Section titled “Vanilla JS”import { openWidget, closeWidget } from "https://cdn.docuworm.ai/docuworm.js";
const widget = document.querySelector("docuworm-chat");openWidget(widget);closeWidget(widget);const ref = useRef<HTMLElement | null>(null);
function open() { if (ref.current) openWidget(ref.current);}
function close() { if (ref.current) closeWidget(ref.current);}const widget = ref<HTMLElement | null>(null);
function open() { if (widget.value) openWidget(widget.value);}
function close() { if (widget.value) closeWidget(widget.value);}Svelte
Section titled “Svelte”let widget: HTMLElement | null = null;
function open() { if (widget) openWidget(widget);}
function close() { if (widget) closeWidget(widget);}Recipe: wait for thread and sync to backend
Section titled “Recipe: wait for thread and sync to backend”Vanilla JS
Section titled “Vanilla JS”import { openWidget, waitForThreadId,} from "https://cdn.docuworm.ai/docuworm.js";
const widget = document.querySelector("docuworm-chat");openWidget(widget);const threadId = await waitForThreadId({ element: widget, timeoutMs: 30000 });
await fetch("/api/docuworm/thread", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ threadId }),});useEffect(() => { if (!ref.current) return;
openWidget(ref.current); waitForThreadId({ element: ref.current }).then(async (threadId) => { await fetch("/api/docuworm/thread", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ threadId }), }); });}, []);onMounted(() => { if (!widget.value) return; openWidget(widget.value); waitForThreadId({ element: widget.value }).then((threadId) => { return fetch("/api/docuworm/thread", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ threadId }), }); });});Svelte
Section titled “Svelte”onMount(() => { if (!widget) return; openWidget(widget); waitForThreadId({ element: widget }).then((threadId) => { return fetch("/api/docuworm/thread", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ threadId }), }); });});Recipe: hybrid context ingestion
Section titled “Recipe: hybrid context ingestion”Vanilla JS
Section titled “Vanilla JS”import { uploadFile, uploadFileFromUrl, addSources,} from "https://cdn.docuworm.ai/docuworm.js";
const widget = document.querySelector("docuworm-chat");
await uploadFile(fileInput.files[0], widget);await uploadFileFromUrl("https://example.com/statement.pdf", widget, { filename: "statement.pdf",});
addSources( [{ title: "Case Summary", text: "Customer reported duplicate charge.", category: "case" }], widget,);React / Vue / Svelte
Section titled “React / Vue / Svelte”Use the same helper calls as Vanilla and pass the framework-held widget element reference.