DatoCMS Site Search > React search widget

    React search widget

    In addition to the low-level API request presented in the previous section, our react-datocms package also includes a React hook that you can use to render a full-featured Site Search widget on your website.

    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:

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

    You can then use the useSiteSearch hook like this:

    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,
    buildTriggerId: '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 and the data returned by the hook.

    Complete example

    The following example uses the 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.

    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' },
    buildTriggerId: '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>
    );
    }