Chat History — Citation Links

Change the class, the attributes and the tooltip of each citation link in an answer.

Each [1] in an answer is a link to the source it cites. Below we hook into every citation link, mark it with a class and a data attribute, give it a tooltip, and then read a field that the response does not send by default.

You need a working Chat History page first. See Chat History — Quick Start.

Give the answer layout an onCitationLink function. Set it on client.ui.conversation, the panel the answers show in. It covers every message in the panel, follow-ups and reopened threads included:

function onCitationLink({ addClass, setAttribute }, { source }) {
  addClass("my-citation-link");
  if (!source) {
    return;
  }
  setAttribute("data-title", source.title);
}

client.ui.conversation.useLayouts({
  answer: { onCitationLink },
});

The second argument is { source, index }. source is the cited item from the response's sources, and index is its position, counted from 0. source can be undefined, so check it before you read from it.

The first argument holds the methods that change the link:

MethodWhat it does
addClass(name), removeClass(name)Add or remove a class on the link.
setAttribute(key, value), removeAttribute(key)Set or remove an attribute, such as data-title. The SDK escapes the value. Use addClass for classes.
setTooltipText(text)Show plain text in the tooltip.
setTooltipHtml(html)Show HTML in the tooltip. Escape every value from source with escapeHtml.
escapeHtml(text)Escape text for use in HTML.

The SDK calls the function each time it renders the answer, and it renders the answer many times as the text streams in. Only change the link inside the function.

Add a tooltip

Put content in the link's tooltip with setTooltipText or setTooltipHtml. This one shows the source's title and date:

function onCitationLink({ setTooltipHtml, escapeHtml }, { source }) {
  if (!source) {
    return;
  }
  const date = new Date(source.published_at).toLocaleDateString();
  setTooltipHtml(
    `<span class="title">${escapeHtml(source.title)}</span>` +
    `<span class="date">${date}</span>`
  );
}

The SDK styles already place the tooltip above the link and show it on hover. Style what you put inside it:

.miso-citation-tooltip .title {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  width: max-content;
  max-width: 12rem;
  overflow: hidden;
  font-weight: 600;
}
.miso-citation-tooltip .date {
  display: block;
  margin-top: 0.5em;
}

Use more source fields

source carries only the fields that the request asks for. product_id and title always arrive, whether source_fl names them or not. By default, the conversation workflow requests these fields:

["cover_image", "url", "created_at", "updated_at", "published_at", "title", "authors"]

To read any other field, name it in source_fl in the request payload. The list replaces the default, so start from the default and add your field.

client.ui.conversation.useApi({
  source_fl: ["cover_image", "url", "created_at", "updated_at", "published_at", "title", "authors", "categories"],
});

source.categories is then available in onCitationLink. A custom attribute uses its dotted path, such as custom_attributes.section. See source_fl on the question request in the API Reference, and the field names in Product Schema.

source_fl applies to the questions the reader asks in the panel. A thread the reader reopens loads its answers through a request that takes no field list, so a field you added can be missing there. Check for the field before you read it.

If it does not work

SymptomCause
The tooltip shows undefinedThe field is not in source_fl.
Every link stays plainThe layout is on client.ui.history. Set it on client.ui.conversation.
A field is missing in a reopened threadsource_fl applies to the questions asked in the panel only.
The tooltip shows raw tagsThe HTML went to setTooltipText. Use setTooltipHtml.
Nothing changes and error shown in console logThe function throws. The SDK logs the error and leaves the link as it was.