Javascript match and highlight advanced

I’m trying to build a search engine with javascript and PHP. So far, I have had success, but I still have a bit problem with highlighting search terms and limiting the words. The backend response is returning a JSON with a title and description, and the description could be long, so I want to limit the text and highlight those words that the user is searching for.

So basically, if backend response is like:

[{
    "title": "Test topic",
    "description": "<p>This topic contains some words that user is searching for</p> 
    <div><h1>It could contain anything</h1>
    <p> It could contain anything. Important thing is that it should work.</p>
    <img src="some_pic.jpg/>"
   }]

So, if I’m searching for something like “What important topic contains”. The user should see a parsed version of the description (or whatever string given), with limiting the text radius around the search term. And for this, perfect response would be like:

This topic contains some words that user… It could contain
anything. Important thing is that it would…

So I didn’t pay attention to the details here in words, to be exact with the radius, but I think you got the idea.

So what I did so far is

  • map the response from the backend
  • delete html code (in order to prevent ex. “…ong>”) `
  • split the search term words and execute the function to find them, make them bold and make a radius around them
  • show to the user in a view

Where is the problem? I have no logic to match 2 words, I’m splitting search term, creating an array and pushing parsed version into that array.

And it looks like: (important part of the component)

{
  searchResults.length > 0 ? (
    <div>
      <span className={`text-xs text-blue`}>Threads</span>
      {searchResults?.map((searched: any, index: Key) => {
        // Replace html code (just in case)
        const searchTerm = searched.description.replace(/</?[^>]+(>|$)/g, " ");

        // Create array to push search term
        const searchArray: any[] = [];

        // Split search words into array and match results separately
        search.split(" ").map((text, i) => {
          // This function will be in the next code
          searchArray.push(searchText(searchTerm, text));
        });

        // Just a view here
        return (
          <Link key={index} href={"/forum/thread/" + searched?.slug}>
            <article
              className={`w-full bg-gray-dark  mb-2 px-3 py-1.5 rounded-xl text-gray-light`}
            >
              <h2>{searched.title}</h2>
              {searchArray.map((match, i) => {
                return (
                  <>
                    {/*Just in case, show it as html*/}
                    <div
                      className={`quill post-content text-xs text-gray`}
                      dangerouslySetInnerHTML={{ __html: match }}
                    />
                  </>
                );
              })}
            </article>
          </Link>
        );
      })}
    </div>
  ) : null;
}

And finally, a logic to highlight the text and make a radius around that word.

const searchText = (description: string, search: string) => {
        const radius = 30;
        const indexPosition = description.search(search)
        const startPosition = indexPosition - radius < 0 ? indexPosition : indexPosition - radius
        const endPosition = indexPosition + radius + search.length

        return (`...${description.slice(startPosition, endPosition)}...`).replace(search, `<span class="font-bold text-yellow">${search}</span>`)
    }

So in all that case I would see at the end (with same search term “What important topic contains”)

…anything. Important thing is that it would…
…This topic contains some words that…
…This topic contains some words that user…
… It could contain anything. Important thing…

Basically searching every word couple of times. Any ideas how to improve that logic?