Elasticsearch search-ui with React

1.5k Views Asked by At

I have a React site with aside and main content. I want to use search-ui for searching on the site.

The search bar should be on the aside, and when the user searches for something, results should be displayed on the main content. Aside and main content are two separated react components.

In my aside, I'm configuring search-ui SearchBox like this

<SearchBox
    autocompleteResults={{
        titleField: "title",
        urlField: "url"
    }}
    autocompleteSuggestions={true}
    onSubmit={searchTerm => {
        navigate("/elastic-search?q=" + searchTerm);
    }}
    onSelectAutocomplete={(selection, {}, defaultOnSelectAutocomplete) => {
        if (selection.suggestion) {
            navigate("/elastic-search?q=" + selection.suggestion);
        } else {
            defaultOnSelectAutocomplete(selection);
        }
    }}
/>

So when the user searches something the app will redirect to a separate page named elastic-search and I'm passing the searchTerm in the URL through navigate method.

On MainContent I have results like this:

<Results titleField='title' urlField='url'/>

Now the question is how can I fetch searchTerm and display the results on main content. The structure of the app is like this:

<App>
   <SearchProvider config={config}>
      <Aside /> ---- Here I have <SearchBox>
      <MainContent /> ---- Here I have <Results>
   </SearchProvider>
</App>

When I search the app redirects to /elastic-search with searchTerm in URL, but the results are not displaying. If I refresh the page they are displayed. How can I notify Results or re-render the page, so I can show the searched results.

1

There are 1 best solutions below

4
On

Your Results seems to be missing some parameters and should look something like this:

<>
  <Results
    titleField="title"
    urlField=""
    view={SearchView}
    resultView={SearchResultView}
  />
</>

And your SearchView (Used to override the default view for this Component.) and SearchResultView (Used to override individual Result views.) components, should look something like this:

const SearchView = ({ children }) => {
   return <div>{children}</div>
};

const SearchResultView = ({ result: searchResult }) => {
  return <div>{searchResult.content}</div>
}

Additional suggestion

This is a working example in the Next.js app with import { useRouter } from "next/router"; that needs to be replaced with your routing solution. In the SearchBox component:

export const SearchBoxComponent = () => {
 const router = useRouter();
 return (
  <>
  <SearchBox
    searchAsYouType={true}
    autocompleteResults={{
      titleField: "title",
      urlField: "",
      shouldTrackClickThrough: true,
      clickThroughTags: ["test"],
    }}
    autocompleteSuggestions={true}
    onSubmit={(searchTerm) => {
      const urlEncodedQuery = encodeURI(searchTerm).replace(/%20/g, "+");
      router.push(`/search?q=${urlEncodedQuery}`);
    }}
    ...
    </>
    )
    }