Lähde.

Digitalist's AI-driven web extension

Grounded answers from
your own content.

Lähde delivers AI-powered answers drawn directly from your site's content — embeddable on any website (Webflow, Drupal, plain HTML) as a single script tag.

Embed

One script tag registers all five Lähde boxes — they load from the same bundle. Add <lahde-ask> for a one-shot Q&A box, <lahde-chat> for a multi-turn conversation, <lahde-search-summary> on your search page for an AI summary, <lahde-recommend> on a content page for related links, and <lahde-popular-searches> on your search page for visitor-query pills.

<script src="https://widget.lahde.digitalist.me/lahde.js" defer></script>

<!-- Anywhere: a one-shot question box with cited answers -->
<lahde-ask
  relay="https://lahde-<client>.digitalist.me"
  client="<client>"
  token="<inbound token>">
</lahde-ask>

<!-- Search page: AI summary above the result list -->
<lahde-search-summary
  relay="https://lahde-<client>.digitalist.me"
  client="<client>"
  token="<inbound token>"
  source-name="example.com">
</lahde-search-summary>

<!-- Content page: related links from this page's content + URL -->
<lahde-recommend
  relay="https://lahde-<client>.digitalist.me"
  client="<client>"
  token="<inbound token>"
  content-selector="main">
</lahde-recommend>

Chat — multi-turn conversation

<lahde-chat> keeps a running transcript: the visitor types a message (or taps a suggested follow-up), the box appends a user turn, asks the relay, and appends the assistant reply with its source chips and follow-up chips. Every turn carries the conversation so far as history, so answers stay contextual. Same one script tag as above — no extra include.

<script src="https://widget.lahde.digitalist.me/lahde.js" defer></script>

<!-- Multi-turn chat: history + follow-up chips, contextual answers -->
<lahde-chat
  relay="https://lahde-<client>.digitalist.me"
  client="<client>"
  token="<inbound token>"
  lang="en">
</lahde-chat>

The shared attributes (relay, client, token, lang, timeout-ms) work the same on every box; lahde-chat adds none of its own. Restyle any element from your page CSS via ::part() — parts: panel, log, turn, role, bubble, sources, followups/followup, form, input, submit.

React app? The same five ship as React components in @digitalist/lahde-widget-react: <LahdeAsk />, <LahdeChat />, <LahdeSearchSummary />, <LahdeRecommend />, and <LahdePopularSearches /> — identical props (relay, client, token, lang, timeoutMs).

Popular searches — pills from real visitor queries

<lahde-popular-searches> shows a row of pill links derived from your visitors' actual queries (answered queries only, language-scoped, count ≥ 2). No LLM call — a fast aggregation over the own-stream analytics. Place it on your search page under the search bar. Clicking a pill navigates to your search page with that query pre-filled. The element collapses silently when no data is available yet, so you can deploy it immediately — the pills appear as queries accumulate.

<script src="https://widget.lahde.digitalist.me/lahde.js" defer></script>

<!-- Search page: pills from real visitor queries (stable favorites) -->
<lahde-popular-searches
  relay="https://lahde-<client>.digitalist.me"
  client="<client>"
  token="<inbound token>"
  search-url="/search?keys="
  limit="6">
</lahde-popular-searches>

<!-- Add sort="rising" to show what visitors are asking right now -->
<!-- <lahde-popular-searches sort="rising" ...></lahde-popular-searches> -->

search-url (required) — the base URL for pill hrefs. Use {query} as a placeholder and it will be substituted with the percent-encoded query; omit it and the encoded query is appended directly. Examples: /search?keys= (Drupal Search API), /haku?q={query}&lang=fi (custom form).

Add sort="rising" to show what visitors are searching right now instead of all-time favorites — new terms chart within hours of appearing in the data.

Shadow parts: card, heading, list, pill. A cancellable lahde:popular-search-select CustomEvent fires on pill click (detail: {query, url}) — call event.preventDefault() in your listener to stop anchor navigation and handle the query yourself (e.g. fill a search input in a SPA).

React: <LahdePopularSearches relay client searchUrl /> from @digitalist/lahde-widget-react. The onSelect prop fires with {query, url}; return false to prevent navigation.

Theme

The theme comes from your page: the widget inherits your font, size, and text color automatically. Tune the rest with CSS variables, or restyle any element with ::part() — both from your own stylesheet, no widget changes.

lahde-search-summary {
  --lahde-accent:    #0a0a0a;  /* card left border, hovers, spinner */
  --lahde-bg-subtle: #f7f7f7;  /* card background                   */
  --lahde-border:    #8a8a8a;  /* hairlines + chip borders — keep ≥3:1
                                  against the background (WCAG 1.4.11) */
  --lahde-radius:    0;        /* corner rounding                   */
}

/* Full restyling per element — parts: card, heading, status, answer,
   sources, source-item, source, source-num, related, related-heading,
   related-questions, related-q, disclaimer */
lahde-search-summary::part(card)      { border: 1px solid #d0d0d0; }
lahde-search-summary::part(related-q) { display: block; border: none; }

/* lahde-recommend parts: card, heading, status, list, item, link, reason */
lahde-recommend::part(card)           { border: 1px solid #d0d0d0; }

Versions

lahde.js always serves the latest release — embed it and you get every improvement automatically. Prefer stability? Pin a version: versioned URLs never change and never go away, so you upgrade on your own schedule.

<script src="https://widget.lahde.digitalist.me/lahde-1.0.2.js" defer></script>

All available versions:

Machine-readable manifest

/versions.json publishes the same list as a small JSON document, so integrations (Drupal rag_widgets and others) can discover available bundle versions and the stable pointer without shipping a code update per release. Poll it periodically and offer an admin version picker.

curl https://widget.lahde.digitalist.me/versions.json
{
  "generated_at": "2026-01-01T00:00:00.000Z",  // build time, ISO 8601
  "stable":  "1.0.2",             // current release
  "latest":  "1.0.2",
  "bundle_url_template": "https://widget.lahde.digitalist.me/lahde-{version}.js",
  "stable_url": "https://widget.lahde.digitalist.me/lahde.js",
  "versions": [                       // newest first
    { "version": "1.0.2", "url": "…/lahde-1.0.2.js", "is_stable": true, "is_latest": true }
  ]
}