Ais-highlight rending <em> tag instead of highlighting

Hi all. In the course of upgrading packages (webpack, webpack loaders, babel, vue cli, etc.) in our build, I seem to have broken something with Algolia highlighting and for the life of me, I can’t get it working again. Everything is else working except that ais-highlight is rendering <em> tags around the highlighted results instead of actually highlighting them.

I’ve upgraded to algoliasearch@4.5.1 and vue-instantsearch@3.2.0 but I’m still seeing the issue. What am I missing?? Appreciate the help!

Expected:
<h3><a href="/test-url"><span class="ais-Highlight"><mark class="ais-Highlight-highlighted">Test</mark> information</span></a></h3>

Actual:
<h3><a href="/test-url"><span class="ais-Highlight">&lt;em&gt;Test&lt;/em&gt; information</span></a></h3>

template:

<ais-infinite-hits :escapeHTML="false" :class-names="{'ais-InfiniteHits-loadMore': 'button is-warning is-medium'}">
<template slot="item" slot-scope="{ item }">
    <div class="cols is-right-image box">
        <div>
            <p v-if="item.contentType != 'Other'" class="tag is-medium is-light is-flat"><ais-highlight :hit="item" attribute="contentType" /></p>
            <h3><a :href="item.url"><ais-highlight :hit="item" attribute="title" /></a></h3>
            <p><small>
                <span v-if="item.relevanceDate && item.contentType == 'News'"><span>{{ moment(item.relevanceDate).format("MMM D, YYYY") }}</span></span>
            </small></p>
        </div>
        <figure v-if="item.imageUrl">
            <div class="progressive">
                <img class="lazy" style="" v-progressive="item.imageUrl" src="/Frontend/Images/thumbnail-placeholder.png" alt="" />
            </div>
        </figure>
    </div>
</template>

OK, well I feel like an idiot for not noticing the very relevant :escapeHTML="false" property on the ais-infinite-hits tag. Changing that to true makes the ais-highlight tags render as properly working mark tags!

But now I’m faced with another issue. My hit title sometimes has HTML tags in it but the tags are rendered as escaped HTML regardless of the :escapeHTML setting. I am assuming this is why escapeHTML was originally set to false, but the setting no longer seems to work as expected.

So here’s what I have now:

<ais-infinite-hits :escapeHTML="true" :class-names="{'ais-InfiniteHits-loadMore': 'button is-warning is-medium'}">
<template slot="item" slot-scope="{ item }">
<div class="cols is-right-image box">
    <div>
        <p v-if="item.contentType != 'Other'" class="tag is-medium is-light is-flat"><ais-highlight :hit="item" attribute="contentType" /></p>
        <h3><a :href="item.url"><ais-highlight :hit="item" attribute="title" /></a></h3>
        <p><small>
            <span v-if="item.relevanceDate && item.contentType == 'News'"><span>{{ moment(item.relevanceDate).format("MMM D, YYYY") }}</span></span>
        </small></p>
    </div>
    <figure v-if="item.imageUrl">
        <div class="progressive">
            <img class="lazy" style="" v-progressive="item.imageUrl" src="/Frontend/Images/thumbnail-placeholder.png" alt="" />
        </div>
    </figure>
</div>
</template>
</ais-infinite-hits>

And what gets rendered in the HTML is:

<span class="ais-Highlight">This is an <mark class="ais-Highlight-highlighted">example</mark> title with &lt;span class="my-class"&gt;html tags&lt;/span&gt;+, that are not rendered correctly.</span> v

Which I suppose makes sense because I told it to escape HTML.
HOWEVER, if I set escapeHTML to false, I get:

<span class="ais-Highlight">This is an &lt;em&gt;example&lt;/em&gt; title with &lt;span class="my-class"&gt;html tags&lt;/span&gt;+, that are not rendered correctly.</span>

and the highlighting no longer works.

TL;DR: ais-highlight only works if escapeHTML is set to TRUE on ais-infinite-hits, and escapeHTML seems to have no effect on HTML tags within the text passed to ais-highlight attribute. The title is being stored in our Algolia index as unescaped HTML tags.

Hi,

Getting a minimal reproducible example helps us better understand the problem. We provide a CodeSandbox template to avoid spending time setting up the environment.

Please get back to us with the link so we can work on a solution.

Thanks!

I will work on setting up a CodeSandbox Samuel, but can you tell me if any of the hits in that search client have HTML tags in the fields? That’s what stopped me from setting one up initially.

Here’s a sandbox that replicates the issue with ais-highlight where when escapeHTML is set to false, the highlight shows <em> tags instead of highlighting. https://codesandbox.io/s/vigorous-http-1knwn

Hi @tsulli,

Yes with escapeHTML: false it’s expected that the highlighting doesn’t work. We use a placeholder to safely inject the em (or a custom tag) in the value. If the option is disabled we don’t perform this replacement and we use the raw data of the engine which by default contains em. Vue doesn’t print the HTML by default hence the issue.

It would be helpful to have an example with your data. Or at least could you provide an example of the data stored in one of your records? It would help to better understand the issue.

Thank you!

Thanks Samuel. If this is expected behavior for ais-highlight, could a note be added to the documentation somewhere? I’ve spent a good bit of time trying to get this working so far and that would have helped.

I’ve updated the sandbox to use our dev index with some sample data that is equivalent to our live data. I believe it demonstrates the issue as described, please take a look when you have a chance. Thanks again.

Hi @tsulli,

If you trust the content of the records the usage <ais-highlight> is not required. You can disable the escaping with escapeHTML: false and use the raw value of the highlighted results. By default Vue escapes the raw HTML so you’ve to use v-html to render the attribute. Here is the CodeSandbox updated.

<template>
  <ais-infinite-hits :escapeHTML="false">
    <template slot="item" slot-scope="{ item }">
      <article>
        <h1 v-html="item._highlightResult.title.value" />
      </article>
    </template>
  </ais-infinite-hits>
</template>

Thank you! I can definitely use this to get the results I need. Appreciate the help :slight_smile: