# Creating custom adapter

This document shows how to create your own adapter. It may prevent duplicating the code in the theme.

# Structure of the Adapter and AdapterFactory

AdapterFactory function passing to the algolia.configuration.adapters array in the middleware.config.js has the following structure:

const adapterFactory: AdapterFactory = (settings: AlgoliaMiddlewareConfig): Adapter => {
  return {
    name: 'my-custom-adapter',
    transform: async (params: TransformParams, fnName: FUNCTION_NAME): Promise<TransformParams> => {
      return params;
    },
    normalize: async (response: AlgoliaResponse, fnName: FUNCTION_NAME, args): Promise<NormalizedResponse> => {
      const normalizeResponse = // ...
      return normalizeResponse(response);
    }
  }
}

Factory accepts AlgoliaMiddlewareConfig as an argument which is an algolia.configuration passed from the middleware.config.js. Factory must return an Adapter with the following structure:

interface Adapter {
  name: string;
  transform: (params: TransformParams, fnName?: string) => Promise<TransformParams>;
  normalize: (response: AlgoliaResponse, fnName?: string, args?: any[]) => Promise<any>;
}

# transform function

The transform function is called before every request to Algolia. TransformParams might be one of the types listed below. To find out which one, use the second argument called fnName:

fnName Type
search SearchIndexArgs (opens new window)
searchForFacetValues SearchForFacetValuesArgs (opens new window)
multipleQueries MultipleQueriesArgs (opens new window)
searchWithHelper SearchWithHelperArgs (opens new window)

Inside you can modify params before they are sent to Algolia.

WARNING

Your adapter should support all available types of parameters.

# normalize function

The normalize function is called after Algolia sends the response but before the Vue storefront sends it to the client. Inside of it, you can map it or fetch more data based on the received information.

If you want to use searchGetters on this data, it has to match the AgnosticResponse type.

type AgnosticResponse = {
  _categoryTree: AgnosticCategoryTree;
  _pagination: AgnosticPagination;
  _sortOptions: AgnosticSort;
  _breadcrumbs: AgnosticBreadcrumb[];
  _filters: AgnosticFilter[];
}

WARNING

Keep in mind that responses can be in different shapes depending on the entity. Use the args parameter to get the name of the current entity.

const getEntityFromArgs = (args: Array<any>): string => args[args.length - 2].entity;