# React search widget

In addition to the [low-level API request](https://www.datocms.com/docs/site-search/base-integration.md) presented in the previous section, our [`react-datocms`](https://github.com/datocms/react-datocms/blob/master/docs/site-search.md)package also includes a **React hook** that you can use to render a full-featured Site Search widget on your website.

> [!POSITIVE] You're in charge of the UI!
> The hook only handles the form logic: you are in complete and full control of how your form renders down to the very last component, class or style.

### Setup

First of all, install the required npm packages in your React project:

Terminal window

```bash
npm install --save @datocms/cma-client-browser
```

You can then use the `useSiteSearch` hook like this:

```jsx
import { useSiteSearch } from 'react-datocms';
import { buildClient } from '@datocms/cma-client-browser';

const client = buildClient({ apiToken: 'YOUR_API_TOKEN' });

const { state, error, data } = useSiteSearch({
  client,
  searchIndexId: '7497',
  // optional: you can omit it you only have one locale, or you want to find results in every locale
  initialState: { locale: 'en' },
  // optional: to configure how to present the part of page title/content that matches the query
  highlightMatch: (text, key, context) =>
    context === 'title' ? (
      <strong key={key}>{text}</strong>
    ) : (
      <mark key={key}>{text}</mark>
    ),
  // optional: defaults to 8 search results per page
  resultsPerPage: 10,
});
```

Please follow the `react-datocms` documentation to read more about at the [configuration options](https://github.com/datocms/react-datocms/blob/master/docs/site-search.md#initialization-options) and the [data returned by the hook](https://github.com/datocms/react-datocms/blob/master/docs/site-search.md#returned-data).

### Complete example

The following example uses the [`react-paginate`](https://www.npmjs.com/package/react-paginate) npm package to simplify the handling of pagination. You can build your own pagination using the `data.totalPages` property to get the total number of pages, `state.page` to get the current page, and `state.setPage(page)` to trigger a page change.

```jsx
import { useState } from 'react';
import { buildClient } from '@datocms/cma-client-browser';
import ReactPaginate from 'react-paginate';
import { useSiteSearch } from 'react-datocms';

const client = buildClient({ apiToken: 'YOUR_API_TOKEN' });

function App() {
  const [query, setQuery] = useState('');

  const { state, error, data } = useSiteSearch({
    client,
    initialState: { locale: 'en' },
    searchIndexId: '7497',
    resultsPerPage: 10,
  });

  return (
    <div>
      <form
        onSubmit={(e) => {
          e.preventDefault();
          state.setQuery(query);
        }}
      >
        <input
          type="search"
          value={query}
          onChange={(e) => setQuery(e.target.value)}
        />
        <select
          value={state.locale}
          onChange={(e) => {
            state.setLocale(e.target.value);
          }}
        >
          <option value="en">English</option>
          <option value="it">Italian</option>
        </select>
      </form>
      {!data && !error && <p>Loading...</p>}
      {error && <p>Error! {error}</p>}
      {data && (
        <>
          {data.pageResults.map((result) => (
            <div key={result.id}>
              <a href={result.url}>{result.title}</a>
              <div>{result.bodyExcerpt}</div>
              <div>{result.url}</div>
            </div>
          ))}
          <p>Total results: {data.totalResults}</p>
          <ReactPaginate
            pageCount={data.totalPages}
            forcePage={state.page}
            onPageChange={({ selected }) => {
              state.setPage(selected);
            }}
            activeClassName="active"
            renderOnZeroPageCount={() => null}
          />
        </>
      )}
    </div>
  );
}
```

## Related content in "DatoCMS Site Search"

- [Site Search Overview](https://www.datocms.com/docs/site-search.md)
- [Configuration](https://www.datocms.com/docs/site-search/configuration.md)
- [How the crawling works](https://www.datocms.com/docs/site-search/how-the-crawling-works.md)
- [Perform searches via API](https://www.datocms.com/docs/site-search/base-integration.md)
- [React search widget](https://www.datocms.com/docs/site-search/widget.md)
- [Vue search widget](https://www.datocms.com/docs/site-search/vue-search-widget.md)