
A zero-dependency drop-in script that lets you:
It ships as a single file and exposes three globals for flexibility:
ElementInspector (recommended): high-level orchestrator for capture + explanationElementCapture: low-level capture utilityElementMeaning: low-level Gemini clientInclude the single script:
<script src="/element-intelligence.js"></script>
This exposes global ElementInspector, ElementCapture, and ElementMeaning objects.
<button id="start-capture">Start capture</button>
<button id="stop-capture">Stop capture</button>
<script>
// Configure once at startup
ElementInspector.configure({
apiKey: '<YOUR_GEMINI_API_KEY>',
applicationDescription: 'A SaaS dashboard for managing subscriptions and invoices'
});
// Start capture and auto-explain the clicked element
document.getElementById('start-capture').addEventListener('click', function() {
ElementInspector.captureAndExplain()
.then(function(out) {
console.log('Captured element:', out.element);
if (out.result && out.result.ok) {
console.log('[Explanation]', out.result.answerText);
} else {
console.warn('Explanation failed:', out.result && (out.result.message || out.result.code));
}
})
.catch(function(err) {
console.warn('Capture or explanation error:', err && err.message);
});
});
// Stop capture programmatically
document.getElementById('stop-capture').addEventListener('click', function() {
ElementInspector.stop();
});
</script>
Esc to cancel capture.preventDefault() and stopImmediatePropagation().Open the included demo with your API key provided via URL parameter:
/demo.html?api_key=YOUR_GEMINI_API_KEY
The demo logs both the captured element and the explanation to the browser console.
ElementInspector.configure(options): Defaults — sets defaults and returns the current defaults snapshot
apiKey?: string — Gemini API keymodel?: string — defaults to gemini-2.5-flash-liteapplicationDescription?: string — high-level description of your appgenerationConfig?: { temperature?: number, topP?: number, topK?: number, maxOutputTokens?: number }timeoutMs?: number — default DEFAULT_TIMEOUT_MS (see constants)ElementInspector.captureOnce(): Promise<{ element: Element, eventType: string }> — enters capture mode and resolves on next clickElementInspector.explainElement(element, overrides?): Promise<AnalyzeResult> — runs explanation for a provided elementElementInspector.captureAndExplain(overrides?): Promise<{ element: Element, eventType: string, result: AnalyzeResult }> — captures and explains in one callElementInspector.stop(): void — cancels an in-progress capture (delegates to ElementCapture.stop())ElementInspector.defaults: Defaults — current default configurationElementInspector.version: stringWhere overrides may include: apiKey, model, applicationDescription, pageHtml, generationConfig, timeoutMs, extraContext, and the following callbacks:
onExplanationStart?: (element: Element) => void — callback fired right after element capture, before the explanation API call. Ideal for showing a loading state.onExplanationEnd?: () => void — callback fired after the explanation API call completes (on both success and failure). Ideal for hiding a loading state.ElementCapture.start(): Promise<{ element: Element, eventType: string }>ElementCapture.stop(): voidElementCapture.isCapturing(): booleanElementCapture.getLastCapturedElement(): Element | nullElementCapture.version: stringElementMeaning.analyze(options): Promise<AnalyzeResult>
apiKey: string (required)applicationDescription: string (required)pageHtml: string (required)element?: Element — DOM element to analyze (or provide elementInfo)elementInfo?: object — custom element context if DOM is not availableextraContext?: object | string — optional additional contextmodel?: string — defaults to gemini-2.5-flash-litegenerationConfig?: { temperature?: number, topP?: number, topK?: number, maxOutputTokens?: number }timeoutMs?: number — default DEFAULT_TIMEOUT_MSok: booleananswerText?: string — present when ok is trueraw?: any — raw Gemini responsemodel?: stringcode?: string — error code when ok is falsemessage?: string — error message when ok is falsestatus?: number — HTTP status when availableMISSING_API_KEYINVALID_API_KEYRATE_LIMITEDFORBIDDENBAD_REQUESTNOT_FOUNDSERVER_ERRORNETWORK_ERRORUNKNOWNAvailable at ElementMeaning.constants:
DEFAULT_MODELTEXT_CONTENT_LIMIT — default 4000OUTER_HTML_LIMIT — default 100000DEFAULT_TIMEOUT_MS — default 30000