Vue Storefront is now Alokai! Learn More
Frontend Modification

Frontend

There are a few manual steps required to integrate the Coveo module into your storefront. We will guide you through the process of integrating the module into your storefront. In most cases, you will need to replace the existing component with the Coveo component.

Register Nuxt module (only for Vue)

Open the nuxt.config.ts and at the following modules and runtimeConfig:

{
  // ...
  runtimeConfig: {
    public: {
      coveoOrganizationId: import.meta.env.NUXT_PUBLIC_COVEO_ORGANIZATION_ID,
      coveoAccessToken: import.meta.env.NUXT_PUBLIC_COVEO_ACCESS_TOKEN,
    },
  },
  // ...
  modules: [
    // ...
    '@sf-modules/coveo/module',
  ],
}

Environment variables

Add environment variables in your .env file:

NEXT_PUBLIC_COVEO_ORGANIZATION_ID=xxxxyyyyzzzz
NEXT_PUBLIC_COVEO_ACCESS_TOKEN=xxx-yyyy-zzz-www-cccccccccc

Import the CoveoSearch component and replace the existing UiSearch component in the template. It will enable Quick Search with suggestions from Coveo.

// storefront-unified-nextjs/layouts/DefaultLayout.tsx
import { CoveoSearch } from '@sf-modules/coveo' // [code++]

return (
  <>
    {/* ... */}
    {/* <Search className="hidden md:block flex-1" /> */}
    <CoveoSearch className="hidden md:block flex-1" />
    {/* ... */}
    {/* <Search onAfterSearch={searchModal.close} /> */}
    <CoveoSearch close={searchModal.close} />
    {/* ... */}
  </>
)

Search results and category pages

Search results and category pages are separate pages but the required steps are similar. You need to replace the useSearchProducts with useCoveoSearchProducts. It will enable AI-Powered Search Results and Dynamic Faceting.

// storefront-unified-nextjs/pages/search.tsx
// Import
import { useCoveoSSR, useCoveoSearchProducts } from '@sf-modules/coveo'; // [code++]

// Remove
import { resolveSearchProductsArgsFromQuery } from '~/helpers'; // [code--]
import { prefetchSearchProducts, useSearchProducts } from '~/hooks'; // [code--]

// Update getServerSideProps function
export const getServerSideProps = createGetServerSideProps(
  { i18nNamespaces: ['category', 'icons'] },
  async (context) => {
    const { queryClient } = context;

    const state = await useCoveoSSR(queryClient, context.resolvedUrl);

    if (!state) {
      return {
        notFound: true,
      };
    }

    return {
      props: {
        dehydratedState: dehydrate(queryClient),
      },
    };
  },
);

// Update the component
export function SearchPage() {

  {/* const productsCatalog = useSearchProducts(resolveSearchProductsArgsFromQuery(query)); */}
  const productsCatalog = useCoveoSearchProducts(); // [code++]
// storefront-unified-nextjs/pages/category/[[...slug]].tsx
// Import
import { useCoveoSSR, useCoveoSearchProducts } from '@sf-modules/coveo'; 
// Remove
import { resolveSearchProductsArgsFromQuery } from '~/helpers'; 
// Replace
import { prefetchSearchProducts, prefetchSearchProducts, useCategory, useCategoryBreadcrumbs, useSearchProducts } from '~/hooks'; // With
import { useCategory, useCategoryBreadcrumbs } from '~/hooks'; 
// Update getServerSideProps function
export const getServerSideProps = createGetServerSideProps(
  { i18nNamespaces: ['category', 'icons'] },
  async (context) => {
    const { queryClient } = context;

    const state = await useCoveoSSR(queryClient, context.resolvedUrl);

    if (!state) {
      return {
        notFound: true,
      };
    }

    return {
      props: {
        dehydratedState: dehydrate(queryClient),
      },
    };
  },
);

// Update the component
export function SearchPage() {

  {/* const productsCatalog = useSearchProducts(resolveSearchProductsArgsFromQuery(query)); */}
  const productsCatalog = useCoveoSearchProducts(); // [code++]

Category Filters

Coveo module is shipped with additional filters components. You need to add or replace the existing filters with the Coveo filters.

// storefront-unified-nextjs/components/CategoryFilters/CategoryFilters.tsx
import { CoveoFilterPrice } from '@sf-modules/coveo'; // [code++]

// Add coveo filter price component in the switch case
return (
  <div className="flex flex-col" data-testid="category-filters">
    {facets.map((facet) => {
      switch (facet.type) {
      // ...
      case 'PRICE': {
        return <CoveoFilterPrice facet={facet} key={facet.name} />;
      }
      // ...
      }
    })}
  </div>
)

Category Page Content

To enable the AI-Powered Search Results you will also need to add Product Card components that will be used to send the click events to Coveo.

// storefront-unified-nextjs/components/CategoryPageContent/CategoryPageContent.tsx

// Import
import { CoveoProductCardVertical } from '@sf-modules/coveo'; // [code++]

// Remove
{/* import { Pagination, ProductCardVertical } from '~/components/ui'; */}
import { Pagination } from '~/components/ui'; // [code++


return (
  <>
    {/* ... */}
    {/* <ProductCardVertical */}
    <CoveoProductCardVertical // [code++]
    {/* ... */}
  </>
)

SSR Coveo Context

For the NextJs application we need to resolve some data on the server side that are available in cookies. To do that we need to use the configureCoveoSSRContext function on each page that is using Coveo in the getServerSideProps function. This function will setup locale and currency in the Coveo context and pass it in the request to the Coveo API in the withAlokai function.

// Pages that are using Coveo
// storefront-unified-nextjs/pages/search.tsx
// storefront-unified-nextjs/pages/category/[[...slug]].tsx

import { configureCoveoSSRContext } from '@sf-modules/coveo/context'; // [code++]

// Update getServerSideProps function
export const getServerSideProps = createGetServerSideProps(
  { i18nNamespaces: ['category', 'icons'] },
  async (context) => {
    // ...
    configureCoveoSSRContext(context);
    // ...
  },
);

Other

You should also replace the useSearchProducts with useCoveoSearchProducts in other components that are using it.

Keep the original destruct properties unless you want to change the behavior of the component or the composable.

List of components that are using useSearchProducts:

  • storefront-unified-nuxt/components/CategoryFilters/CategoryFilters.vue
  • storefront-unified-nuxt/components/CategorySidebar/CategorySidebar.vue
  • storefront-unified-nuxt/components/CategorySorting/CategorySorting.vue
  • storefront-unified-nuxt/composables/useFacet/useFacet.ts
other
<script setup lang="ts">
import { useCoveoSearchProducts } from '@sf-modules/coveo';
// ...
const { original_destruct_properties } = useCoveoSearchProducts();
// ...
</script>

VSCode users

It is possible that type inference for value returned from useNuxtApp won't work correctly for VSCode users. In order to fix it, you need to update TypeScript version, to be derived from workspace. You can read more about it here. It's not only related to Volar but also to the new Vue Official VSCode extension.