Elaras/

Block Rendering

Blocks are structured UI components that an Elaras agent returns alongside a text message — carousels, booking pickers, forms, rating widgets, and more. Elaras ships ready-made renderers so you don't write any block UI code yourself.

Setup

Add two tags to your page — no build step needed:

<link rel="stylesheet" href="https://ask-api.elaras.ai/sdk/blocks.css">
<script src="https://ask-api.elaras.ai/sdk/blocks.js"></script>

The script exposes window.ElarasBlocks with renderBlock and renderBlocks.

Rendering blocks

Blocks arrive on the done event alongside the text response:

const { renderBlocks } = window.ElarasBlocks

for await (const event of client.stream(sessionId, message)) {
  if (event.type === 'done' && event.blocks?.length) {
    renderBlocks(messagesEl, event.blocks, (text) => client.stream(sessionId, text))
    messagesEl.scrollTop = messagesEl.scrollHeight
  }
}

renderBlocks(container, blocks, onSend)

ArgumentTypeDescription
containerHTMLElementElement to append blocks into
blocksBlock[]Block array from the chat event
onSend(text: string) => voidCalled when the user interacts with a block (button click, form submit, slot selection, etc.)

renderBlock(container, block, onSend)

Same signature but renders a single block. Unknown block.type values are silently ignored.

Image loading and scroll

Card images load asynchronously. When one finishes loading, a elaras:imageload CustomEvent bubbles up through the DOM. Listen on your messages container and re-scroll:

messagesEl.addEventListener('elaras:imageload', () => {
  messagesEl.scrollTop = messagesEl.scrollHeight
})

Theming

All styles use CSS custom properties. Override them on your container element to match your brand:

.my-chat {
  --ec-primary:      #ff6600;
  --ec-bg:           #ffffff;
  --ec-surface:      #f5f5f5;
  --ec-text:         #111111;
  --ec-text-muted:   #777777;
  --ec-border:       #e0e0e0;
  --ec-input-bg:     #fafafa;
  --ec-input-border: #cccccc;
}

Block types

elaras.card

A single card with optional image, metadata, and CTA.

{
  "type": "elaras.card",
  "spec": {
    "title": "2-bed flat, Shoreditch",
    "subtitle": "£1,200 pcm",
    "description": "Modern apartment with private balcony.",
    "image_url": "https://example.com/photo.jpg",
    "badge": "Available now",
    "metadata": [
      { "label": "beds", "value": "2" },
      { "label": "baths", "value": "1" }
    ],
    "cta": { "label": "View property", "url": "https://example.com/listing/123" }
  }
}

cta.sends sends a preset message into the chat instead of opening a URL.


elaras.carousel

A horizontally scrollable row of cards.

{
  "type": "elaras.carousel",
  "spec": {
    "cards": [ ...card specs... ]
  }
}

elaras.button_group

A set of action buttons.

{
  "type": "elaras.button_group",
  "spec": {
    "label": "What would you like to do?",
    "layout": "row",
    "buttons": [
      { "label": "Book a viewing", "sends": "I'd like to book a viewing", "style": "primary" },
      { "label": "Ask a question", "sends": "I have a question", "style": "outline" }
    ]
  }
}

layout is "row" (default) or "column".


elaras.form

An inline form. On submit, field values are interpolated into sends_template and sent as a chat message.

{
  "type": "elaras.form",
  "spec": {
    "title": "Request a callback",
    "submit_label": "Send request",
    "sends_template": "Callback request — Name: {name}, Phone: {phone}",
    "fields": [
      { "name": "name",  "label": "Full name",     "type": "text",  "required": true },
      { "name": "phone", "label": "Phone number",  "type": "tel",   "required": true },
      { "name": "time",  "label": "Best time",     "type": "select", "options": ["Morning", "Afternoon", "Evening"] }
    ]
  }
}

Field type can be "text", "email", "tel", "select", or "textarea".


elaras.banner

An info, success, or warning callout.

{
  "type": "elaras.banner",
  "spec": {
    "title": "Offer deadline: 5pm today",
    "body": "The vendor is reviewing all offers this evening.",
    "variant": "warning",
    "cta": { "label": "Make an offer", "sends": "I'd like to make an offer" }
  }
}

variant is "info" (default), "success", or "warning".


elaras.rating

A star rating widget. Replaces itself with a confirmation on selection.

{
  "type": "elaras.rating",
  "spec": {
    "prompt": "How helpful was this?",
    "scale": 5,
    "labels": { "low": "Not helpful", "high": "Very helpful" },
    "sends_template": "{value} out of {scale} stars"
  }
}

elaras.stat

A single highlighted metric.

{
  "type": "elaras.stat",
  "spec": {
    "value": "£1,200,000",
    "label": "Guide Price",
    "sublabel": "Freehold",
    "trend": "up",
    "trend_value": "+8% YoY"
  }
}

trend is "up", "down", or "neutral".


elaras.slots

A time-slot booking picker. Replaces itself with a confirmation on selection.

{
  "type": "elaras.slots",
  "spec": {
    "title": "Choose a viewing time",
    "date_label": "Thursday 19 September",
    "sends_template": "Book viewing: {time} (ref: {id})",
    "slots": [
      { "id": "v1", "time": "10:00 AM", "label": "30 min", "available": true },
      { "id": "v2", "time": "11:00 AM", "label": "30 min", "available": false },
      { "id": "v3", "time": "2:00 PM",  "label": "30 min", "available": true }
    ]
  }
}

elaras.choices

A single or multi-select question. Locks itself after submission.

{
  "type": "elaras.choices",
  "spec": {
    "question": "What type of property are you looking for?",
    "type": "multi",
    "options": ["Flat", "House", "New build", "Period property"],
    "allow_other": true,
    "other_placeholder": "Something else…"
  }
}

type is "single" (default) or "multi".


Emitting blocks from a skill

Return a _blocks key from any skill tool result:

{
  "result": "Here are the closest matches to your search.",
  "_blocks": [
    {
      "type": "elaras.carousel",
      "spec": {
        "cards": [...]
      }
    }
  ]
}

The widget and SDK both handle _blocks automatically.