Step 1: Basic Navigation
Install React Router
There are a few different options for adding routing to a React application, but this guide will utilize React Router. Add it with NPM or Yarn:
NPM
npm install react-router-domYarn
yarn add react-router-domUniversal and Vertical Result Pages
Before you add routing to your application, you’ll add a generic page for both Universal and Vertical Results. In a new folder called pages, add a file called VerticalResultsPage.tsx. When this component is rendered, the Search Headless useSearchActions will set the vertical and execute a vertical query.
// src/pages/VerticalResultsPage.tsx
import { useSearchActions } from "@yext/search-headless-react";
import { StandardCard, VerticalResults } from "@yext/search-ui-react";
import { useEffect } from "react";
interface VerticalResultsPageProps {
verticalKey: string;
}
export const VerticalResultsPage = ({
verticalKey,
}: VerticalResultsPageProps): JSX.Element => {
const searchActions = useSearchActions();
useEffect(() => {
searchActions.setVertical(verticalKey);
searchActions.executeVerticalQuery();
}, [verticalKey, searchActions]);
return <VerticalResults CardComponent={StandardCard} />;
};Create a component called UniversalResultsPage.tsx. Here, setUniversal is called to clear the vertical key before executeUniversalQuery is called. universalResultsConfig is used to create a label for each vertical in the <UniveralResults/>.
// src/pages/UniversalResultsPage.tsx
import { useSearchActions } from "@yext/search-headless-react";
import { UniversalResults, VerticalConfigMap } from "@yext/search-ui-react";
import { useEffect } from "react";
const universalResultsConfig: VerticalConfigMap = {
events: {
label: "Events",
},
locations: {
label: "Locations",
},
artists: {
label: "Artists",
},
};
export const UniversalResultsPage = (): JSX.Element => {
const searchActions = useSearchActions();
useEffect(() => {
searchActions.setUniversal();
searchActions.executeUniversalQuery();
}, [searchActions]);
return <UniversalResults verticalConfigMap={universalResultsConfig} />;
};The last file you’ll add to your pages folder is StandardLayout.tsx. This defines a simple layout for each search page where the SearchBar appears above the search results.
// src/pages/StandardLayout.tsx
import { SearchBar } from "@yext/search-ui-react";
export interface StandardLayoutProps {
page: JSX.Element;
}
export const StandardLayout = ({ page }: StandardLayoutProps): JSX.Element => {
return (
<>
<SearchBar />
{page}
</>
);
};Adding a PageRouter
You need to be able to navigate to the different pages you just created so create a file called PageRouter.tsx where you’ll import BrowserRouter. Any routes defined within the BrowserRouter will be able to use any of the the components and hooks from React Router. Within BrowswerRouter, the Routes component contains each Route you define in routeConfig. You can learn more about BrowserRouter
here
and Routes/Route
here
.
// src/PageRouter.tsx
import { Route, Routes, BrowserRouter } from "react-router-dom";
import { StandardLayout } from "./pages/StandardLayout";
import { UniversalResultsPage } from "./pages/UniversalResultsPage";
import { VerticalResultsPage } from "./pages/VerticalResultsPage";
export const routeConfig: {
label: string,
path: string,
element: JSX.Element,
}[] = [
{
label: "All",
path: "/",
element: <StandardLayout page={<UniversalResultsPage />} />,
},
{
label: "Events",
path: "/events",
element: (
<StandardLayout page={<VerticalResultsPage verticalKey="events" />} />
),
},
{
label: "Locations",
path: "/locations",
element: (
<StandardLayout page={<VerticalResultsPage verticalKey="locations" />} />
),
},
{
label: "Artists",
path: "/artists",
element: (
<StandardLayout page={<VerticalResultsPage verticalKey="artists" />} />
),
},
];
export const PageRouter = () => {
return (
<BrowserRouter>
<Routes>
{routeConfig.map((route) => (
<Route key={route.path} path={route.path} element={route.element} />
))}
</Routes>
</BrowserRouter>
);
};Add PageRouter to App.tsx. After you add it, run your app locally. If you visit
localhost:3000/locations
in your browser, you should see a Vertical Query network request in your browser developer tools with the vertical key set to “locations” and the query set to whatever is in your SearchBar.
// src/App.tsx
import { PageRouter } from "./PageRouter";
const App = (): JSX.Element => {
return (
<div className="flex justify-center px-4 py-6">
<div className="w-full max-w-5xl">
<PageRouter />
</div>
</div>
);
};
export default App;Navigating Between Verticals
You can’t expect for users to have to manually change the URL to search different verticals so you’ll need to add a NavBar component. NavBar will use the Link component from React Router to navigate between the different pages in our application that are defined in routeConfig. You can learn more about Link
here
.
// src/components/NavBar.tsx
import { Link } from "react-router-dom";
import { routeConfig } from "../PageRouter";
import classNames from "classnames";
import { useSearchState } from "@yext/search-headless-react";
export const NavBar = (): JSX.Element => {
const currentVertical = useSearchState((state) => state.vertical.verticalKey);
const isActiveLink = (path: string) =>
path.replace("/", "") === currentVertical ||
(path === "/" && currentVertical === undefined);
const renderLink = (label: string, path: string): JSX.Element => {
return (
<Link key={`${path}_link`} to={path}>
<div
className={classNames(
"whitespace-nowrap py-3 mt-1 font-medium text-md border-b-2 hover:border-gray-300 border-transparent",
{
"text-blue-600 border-blue-600": isActiveLink(path),
}
)}
>
<div className="py-3 px-2">{label}</div>
</div>
</Link>
);
};
return (
<nav className="border-b border-gray-200 text-gray-600 flex space-x-6 font-medium mb-6">
{routeConfig.map((route) => renderLink(route.label, route.path))}
</nav>
);
};Add the NavBar to StandardLayout so that it appears below the SearchBar on every page.
// src/pages/StandardLayout.tsx
import { SearchBar } from "@yext/search-ui-react";
import { NavBar } from "../components/NavBar";
export interface StandardLayoutProps {
page: JSX.Element;
}
export const StandardLayout = ({ page }: StandardLayoutProps): JSX.Element => {
return (
<>
<SearchBar />
<NavBar />
{page}
</>
);
};Now, you should be able to easily navigate between Universal Search and the different verticals in your search experience.
