Create a Store Locator Component | Yext Hitchhikers Platform

What You’ll Learn

In this section, you will:

  • Generate a new Mapbox API Key
  • Utilize the MapboxMap to create a locator component
  • Add the locator component to the locator template

Overview

In this unit, you will create a custom Locator component and add it to a static page template. Your locator will look like:


1. Generate a new Mapbox API Token

The map for your locator is going to be powered by the MapboxMap component from Search UI React. Under the hood, this component utilizes Mapbox GL JS . In order to use the Mapbox APIs, you need to sign up for a Mapbox account and get an API key .

Copy the token you just generated and add it to .env:

YEXT_PUBLIC_MAPBOX_API_KEY=YOUR_MAPBOX_API_KEY
light bulb
Note
All environment variables in Yext Pages must be prefixed with YEXT_PUBLIC. You can learn more about environment variables here .

2. Create a Locator Component

In src/components, add a new file called StoreLocator.tsx and paste the following code:

// src/components/StoreLocator.tsx

import {
  MapboxMap,
  FilterSearch,
  OnSelectParams,
  VerticalResults,
  StandardCard,
} from "@yext/search-ui-react";
import {
  Matcher,
  SelectableStaticFilter,
  useSearchActions,
} from "@yext/search-headless-react";
// Mapbox CSS bundle
import "mapbox-gl/dist/mapbox-gl.css";

const StoreLocator = (): JSX.Element => {
  const searchActions = useSearchActions();

  const handleFilterSelect = (params: OnSelectParams) => {
    const locationFilter: SelectableStaticFilter = {
      selected: true,
      filter: {
        kind: "fieldValue",
        fieldId: params.newFilter.fieldId,
        value: params.newFilter.value,
        matcher: Matcher.Equals,
      },
    };
    searchActions.setStaticFilters([locationFilter]);
    searchActions.executeVerticalQuery();
  };

  return (
    <>
      <div className="flex h-[calc(100vh-242px)] border">
        <div className="flex w-1/3 flex-col">
          <FilterSearch
            onSelect={handleFilterSelect}
            placeholder="Find Locations Near You"
            searchFields={[
              {
                entityType: "location",
                fieldApiName: "builtin.location",
              },
            ]}
          />
          <VerticalResults
            customCssClasses={{ verticalResultsContainer: "overflow-y-auto" }}
            CardComponent={StandardCard}
          />
        </div>
        <div className="w-2/3">
          <MapboxMap
            mapboxAccessToken={YEXT_PUBLIC_MAPBOX_API_KEY || ""}
          />
        </div>
      </div>
    </>
  );
};

export default StoreLocator;

Let’s review what you just added:

  • The MapboxMap component needs to be placed within a container that has a set height. You’ll notice that the outer most div has a Tailwind utility of h-[calc(100vh-242px)]. This is setting the height of the locator to be equal to the height of the screen minus the height of the header and footer.
  • FilterSearch and VerticalResults are placed to the left of the map. When you start typing in the FilterSearch bar and click on one of the locations that appear in the dropdown, the handleFilterSearch function will called. This will run a search for locations that are near the location that you selected.

3. Add StoreLocator to your Locator Template

Import StoreLocator into locator.tsx and replace FilterSearch with your new locator component:

// src/templates/locator.tsx

import "../index.css";
import {
  GetHeadConfig,
  GetPath,
  Template,
  TemplateProps,
  TemplateRenderProps,
} from "@yext/pages";
import PageLayout from "../components/PageLayout";
import StoreLocator from "../components/StoreLocator"; // New
import {
  provideHeadless,
  SearchHeadlessProvider,
} from "@yext/search-headless-react";
import { FilterSearch } from "@yext/search-ui-react";

export const getPath: GetPath<TemplateProps> = () => {
  return `locator`;
};

export const getHeadConfig: GetHeadConfig<TemplateRenderProps> = () => {
  return {
    title: "Turtlehead Tacos Locations",
    charset: "UTF-8",
    viewport: "width=device-width, initial-scale=1",
  };
};

const searcher = provideHeadless({
  apiKey: YEXT_PUBLIC_SEARCH_API_KEY,
  experienceKey: "turtlehead-tacos-locator",
  locale: "en",
  verticalKey: "locations",
});

const Locator: Template<TemplateRenderProps> = () => {
  return (
    <PageLayout>
      <SearchHeadlessProvider searcher={searcher}>
        <div className="mx-auto max-w-7xl px-4">
          <StoreLocator /> // New
        </div>
      </SearchHeadlessProvider>
    </PageLayout>
  );
};

export default Locator;

If your site isn’t running locally already, enter npm run dev in the terminal and go to the locator page. You should see the map to the right of the search bar and results container.

unit Quiz
+20 points
Daily Quiz Streak Daily Quiz Streak: 0
Quiz Accuracy Streak Quiz Accuracy Streak: 0
    Error Success Question 1 of 2

    Search for 'New York City, New York, United States' in the filter search bar. How many locations appear on the map?

    Error Success Question 2 of 2

    What all is required to make your locator component work properly?

    High five! ✋

    You've already completed this quiz, so you can't earn more points.You completed this quiz in 1 attempt and earned 0 points! Feel free to review your answers and move on when you're ready.
1st attempt
0 incorrect
Feedback