Mode A: Frontend-Only
Mode A is the primary, zero-config operating mode for applications with an embedded multimodal AI copilot.
How It Works
Section titled “How It Works”- User triggers the overlay (via Alt+shake, shortcut, button, or touch).
- User drags to select a region (or presses Enter for full viewport).
- The selected region is captured with SnapDOM and delivered as a PNG
Blobto youronResultcallback. - No backend route or API keys are required.
User Snip ───► SnapDOM Canvas ───► PNG Blob ───► truden.onResult(blob) ───► AI Chat AttachmentMulti-Framework Implementations
Section titled “Multi-Framework Implementations”import { useEffect, useState } from "react";import truden from "truden";
export function AIAssistant() { const [image, setImage] = useState<Blob | null>(null);
useEffect(() => { return truden.init({ onResult: (blob: Blob) => setImage(blob), }); }, []);
return <ChatWidget attachment={image} />;}"use client";
import { useEffect } from "react";import truden from "truden";
export function TrudenProvider({ children }: { children: React.ReactNode }) { useEffect(() => { return truden.init({ onResult: (blob: Blob) => { console.log("Captured blob for chat copilot:", blob); }, }); }, []);
return <>{children}</>;}<script lang="ts"> import { onMount } from 'svelte'; import truden from 'truden';
let image = $state<Blob | null>(null);
onMount(() => { return truden.init({ onResult: (blob: Blob) => { image = blob; } }); });</script>
<ChatWidget attachment={image} /><script setup lang="ts">import { onMounted, onUnmounted, ref } from 'vue';import truden from 'truden';
const attachedBlob = ref<Blob | null>(null);let teardown: (() => void) | null = null;
onMounted(() => { teardown = truden.init({ onResult: (blob: Blob) => { attachedBlob.value = blob; }, });});
onUnmounted(() => { teardown?.();});</script>import { Component, OnInit, OnDestroy } from '@angular/core';import truden from 'truden';
@Component({ selector: 'app-chat', standalone: true, template: `<button (click)="openSnipper()">Attach Screen</button>`})export class ChatComponent implements OnInit, OnDestroy { private teardown?: () => void;
ngOnInit() { this.teardown = truden.init({ onResult: (blob: Blob) => console.log('Snippet Blob:', blob) }); }
openSnipper() { truden.open(); }
ngOnDestroy() { this.teardown?.(); }}import { useEffect } from 'react';import truden from 'truden';
export function RootComponent() { useEffect(() => { return truden.init({ onResult: (blob: Blob) => { console.log('TanStack attached blob:', blob); }, }); }, []);
return <ChatWidget />;}import { onMount, onCleanup, createSignal } from "solid-js";import truden from "truden";
export function ChatWidget() { const [image, setImage] = createSignal<Blob | null>(null);
onMount(() => { const teardown = truden.init({ onResult: (blob: Blob) => setImage(blob), }); onCleanup(() => teardown()); });
return <button onClick={() => truden.open()}>Snip Screen</button>;}<button id="snip-btn">Attach Screen</button>
<script type="module"> import truden from "truden";
truden.init({ onResult: (blob) => { // Send blob to your custom chat prompt console.log("Attached blob:", blob); }, });
document.getElementById("snip-btn").addEventListener("click", () => { truden.open(); });</script>