Skip to main content
Version: 2.x

Search engine

When configured with Magento2, Front-Commerce provides search capabilities for your website using different technologies. This guide shows you the different options available to you.

You can configure search and product lists with filters using the following platforms:

Since version 2.15

Front-Commerce supports the native Magento API for search and category listing pages. It means that any Magento search module compatible with its GraphQL API will be used in your Front-Commerce project without any specific work.

KNOWN ISSUE

If you're using ElasticSuite as search engine in Magento, you MUST ensure that you have a version greater than 2.10.6.

See "I have an error Cannot read property 'label' of null with Magento 2 native categories listing" troubleshooting section for details.

WIP

This section is being written. Please contact us if you want to ask any question!

Elasticsearch

Requirements

On Magento2 side, Front-Commerce requires Elasticsuite and its CMS Page search plugin to be installed.

The Elasticsuite installation and configuration procedure can be found in a dedicated page on the project wiki while for the CMS Page search plugin, the setup is detailed in its readme document.

Front-Commerce configuration

First, you need to make sure the Elasticsearch search client is installed with a version that matches your Elasticsearch server version (6 or 7):

npm i @elastic/elasticsearch@7

On Front-Commerce side, you need to enable the Elasticsearch datasource by making changes in your .front-commerce.js file similar to:

.front-commerce.js
module.exports = {
modules: ["./node_modules/front-commerce/modules/datasource-elasticsearch"],
serverModules: [
{ name: "FrontCommerce", path: "server/modules/front-commerce" },
{
name: "Magento2Elasticsearch",
path: "datasource-elasticsearch/server/modules/magento2-elasticsearch",
},
{ name: "Magento2", path: "server/modules/magento2" },
],
};
Known issue

the Elasticsearch server module needs to be enabled before the Magento's module.

Then, in your .env file, you need to define the variables.

.env
FRONT_COMMERCE_ES_HOST=<es_host>
FRONT_COMMERCE_ES_ALIAS=<es_alias>
FRONT_COMMERCE_ES_ELASTICSUITE_VERSION=<es_elasticsuite_version>
info

The prefix value can be found in the admin interface under Stores > Elasticsuite > Base Settings > Indices Settings in the field Indices Alias Name (the default value is magento2).

After restarting Front-Commerce, you should be able run a GraphQL query to search for products, categories and/or pages, for instance:

http://localhost:4000/playground
query Search {
search(query: "whatever you want to search for") {
query
products {
total
products {
sku
name
}
}
categories {
name
}
pages {
identifier
title
}
}
}

If you are using the default theme or the Chocolatine theme, the search bar should now be visible.

Alternative facet filtering

Front-Commerce ElasticSearch module provides an alternative way of filtering with facets. By default, each active facet will "refine" (i.e. substract) results from the search and from the selectable facets. With this alternative way, active facets for one attribute will become additive instead.

In order to activate this feature, set search.refinementFacetsOnly to false in your website.js:

src/config/website.js
   themeColor: "#666699",
search: {
dynamicFacetSize: 10,
ignoredAttributeKeys: [],
attributeFacetMinimumDocumentCount: 1,
authorizedCategoriesFacet: [],
categoryFacetMinimumDocumentCount: 1,
- refinementFacetsOnly: true,
+ refinementFacetsOnly: false,
},
phoneNumber: "01 02 03 04 05",
email: "contact@example.com",

Algolia connected to Magento

Since version 2.13

Requirements

On Magento's side, you need to install and configure the Algolia module for Magento2.

In addition, the attribute category_ids must be configured as both an indexed attribute and as a facet:

  1. under Stores > Configuration > Algolia Search > Products, add category_ids as Searchable in the Attributes parameter
  2. under Stores > Configuration > Algolia Search > Instant Search Result Page, add category_ids in the Facets parameter

You can then run the indexer so that the products are indexed in Algolia's index.

note

category_ids is the only required facets. Depending on your project, you can configure any other attribute to be exposed as a facet by following the same steps.

Front-Commerce configuration

First, you need to make sure the Algolia's search client is installed:

npm i algoliasearch@4.8

On Front-Commerce side, you need to enable the Algolia datasource by making the changes in your .front-commerce.js file similar to:

.front-commerce.js
module.exports = {
modules: ["./node_modules/front-commerce/modules/datasource-algolia"],
serverModules: [
{ name: "FrontCommerce", path: "server/modules/front-commerce" },
{
name: "Magento2Algolia",
path: "datasource-algolia/server/modules/magento2-algolia",
},
{ name: "Magento2", path: "server/modules/magento2" },
],
};
Known issue

the Algolia server module needs to be enabled before the Magento's module.

Front-Commerce retrieves the following parameters from Magento:

On the configured facets, only the attribute name and the facet type are taken into account (Label, Searchable and Create Query rule are ignored for now).

note

Before version 2.21, the facet type was ignored and Front-Commerce behaved as if the facet type was set to Conjunctive.

danger

For performance reason, the configuration retrieved from Magento is cached. As a result, after changing a parameter in the backoffice, the new parameter will be taken into account after at most one minute by Front-Commerce.

After restarting Front-Commerce, you should be able to run a GraphQL query to search for products, categories or pages, for instance:

http://localhost:4000/playground
query Search {
search(query: "whatever you want to search for") {
query
products(params: { from: 0, size: 5 }) {
total
products {
sku
name
}
}
categories(size: 5) {
name
}
pages(size: 5) {
title
}
}
}

If you are using the default theme or the Chocolatine theme, the search bar should now be visible.

Algolia not connected to Magento

Since version 2.23

As of the version 2.23, it's possible to configure Front-Commerce to use Algolia without having to install the Algolia module for Magento2.

Requirements

In that kind of setup, you need to implement your own indexing mechanism to replace the one provided by the Algolia module for Magento2. To help you in that task, we provide a script to check that the indices are compatible with Front-Commerce. This script can be run with the following command:

FRONT_COMMERCE_ALGOLIA_APPLICATION_ID=APPID \
FRONT_COMMERCE_ALGOLIA_API_KEY=ADMIN_API_KEY \
FRONT_COMMERCE_ALGOLIA_INDEX_NAME_PREFIX=INDEX_NAME_PREFIX \
npx front-commerce-algolia-check

The application ID and the admin API can be found in your Algolia account. The index name prefix is a prefix of the indices that Front-Commerce will use. The value on the command line should be the same as the one used to configure the Algolia module.

By default, Front-Commerce is able to search for products, categories and CMS pages, the corresponding indices need to follow some requirements.

For product indices:

  • the indices name must be named after the following pattern: {index_name_prefix}{store_code}_products. For instance, in a setup where the index name is myproject_ and Front-Commerce is configured to expose 2 stores which codes are mystore and mystore2, two indices named myproject_mystore_products and myproject_mystore2_products must be created;
  • to be able to sort results by a field, some extra indices must be created by following the same naming convention and by adding a suffix using the pattern _{sort_field}_asc or _{sort_field}_desc. For instance, to allow sorting by created date (field created_at) ascending and descending, the indices myproject_mystore_products_created_at_asc and myproject_mystore_products_created_at_desc must exist;
  • all documents must have a field sku and it must be retrievable sku. The field must contain the product sku as a string and for configurable product it should be an array of the SKUs of each configuration with the first one being the sku of the configurable product;
  • all documents must have a field category_ids, this field must be searchable and configured as an attribute for facets. It must contain the category ids in which the product is positioned;
  • all documents must have a field price where the price is represented as an object like
{ "EUR": { "default": 42 }, "USD": { "default": 40 } }
note

category_ids is the only required facets. Depending on your project, you can configure others facets in the index. For those facets to be taken into, you also have to configure the Algolia module.

For categories indices:

  • the indices name must be named after the following pattern: {index_name_prefix}{store_code}_categories. For instance, in a setup where the index name is myproject_ and Front-Commerce is configured to expose 2 stores which codes are mystore and mystore2, two indices named myproject_mystore_categories and myproject_mystore2_categories must be created;
  • the objectID field of each document must be the category id as a string.

For CMS page indices:

  • the indices name must be named after the following pattern: {index_name_prefix}{store_code}_pages. For instance, in a setup where the index name is myproject_ and Front-Commerce is configured to expose 2 stores which codes are mystore and mystore2, two indices named myproject_mystore_pages and myproject_mystore2_pages must be created.
  • all documents must have a slug field identifying the corresponding CMS page. This field must be set as retrievable.

Front-Commerce configuration

First, you need to make sure the Algolia's search client is installed:

npm i algoliasearch@4.8

On Front-Commerce side, you need to enable the Algolia datasource by making the changes in your .front-commerce.js file similar to:

.front-commerce.js
module.exports = {
modules: ["./node_modules/front-commerce/modules/datasource-algolia"],
serverModules: [
{ name: "FrontCommerce", path: "server/modules/front-commerce" },
{
name: "StandaloneAlgolia",
path: "datasource-algolia/server/modules/algolia",
},
{ name: "Magento2", path: "server/modules/magento2" },
],
};
Known issue

the Algolia server module needs to be enabled before the Magento's module.

In the .env, you need to define the following environment variables:
.env
FRONT_COMMERCE_ALGOLIA_APPLICATION_ID=APP_ID
FRONT_COMMERCE_ALGOLIA_SEARCH_ONLY_API_KEY=SEARCH_ONLY_API_KEY
FRONT_COMMERCE_ALGOLIA_INDEX_NAME_PREFIX=myproject_

To further configure the Algolia module for instance to define facets, you have to create a configuration provider to override the algoliaConfigProvider.

After restarting Front-Commerce, you should be able to run a GraphQL query to search for products, categories or pages, for instance:

http://localhost:4000/playground
query Search {
search(query: "whatever you want to search for") {
query
products(params: { from: 0, size: 5 }) {
total
products {
sku
name
}
}
categories(size: 5) {
name
}
pages(size: 5) {
title
}
}
}

If you are using the default theme or the Chocolatine theme, the search bar should now be visible.

Attraqt

Since version 2.19

Requirements

Due to the way Attraqt works, you will have to ensure your Attraqt index is Front-Commerce-ready before hand. In order to check this, we have added a simple script that check the basics for you, and tells what's missing from your current index.

Using your Attraqt's search API key, you can execute this command from your Front-Commerce repository:

FRONT_COMMERCE_ATTRAQT_SEARCH_API_KEY=your_api_key npx front-commerce-attraqt-check
info

You can find your search API key by logging in in into the XO console, and navigating to: Search > API Keys

The script should be very quick to execute, and will let you now what needs your attention in your Attraqt index. If you have any doubt on how to change this, do not hesitate to ask your Attraqt CSM.

When you get the ✔️ as a response from the script, you are ready to use Attraqt with Front-Commerce.

Facets

Due to facet IDs not being editable in Attraqt, facets created in your Attraqt console must be based on your Magento attributes exact names.

By example, if you have an attribute fashion_colour in your product and you want to add a facet for it, the facet in attraqt must be based on an attribute named fashion_colour as well, which will create a facet with ID facet-fashion_colour.

Front-Commerce configuration

First, you need to make sure the Attraqt's search client is installed:

npm i @attraqt/xo-js@1.6.0

On Front-Commerce side, you need to enable the Attraqt datasource by making the following changes in your .front-commerce.js file:

.front-commerce.js
module.exports = {
modules: ["./node_modules/front-commerce/modules/datasource-attraqt"],
serverModules: [
{ name: "FrontCommerce", path: "server/modules/front-commerce" },
{
name: "Magento2Attraqt",
path: "datasource-attraqt/server/modules/magento2-attraqt",
},
{ name: "Magento2", path: "server/modules/magento2" },
],
};
Known issue

The Attraqt server module needs to be enabled before the Magento module.

Then, in your .env file, you need to define the FRONT_COMMERCE_ATTRAQT_SEARCH_API_KEY environment variable:

.env
FRONT_COMMERCE_ATTRAQT_SEARCH_API_KEY=yourapikeyvalue

After restarting Front-Commerce, you should be able run a GraphQL query to search for products, categories and/or pages, for instance:

http://localhost:4000/playground
query Search {
search(query: "whatever you want to search for") {
query
products(params: { from: 0, size: 5 }) {
total
products {
sku
name
}
}
categories(size: 5) {
name
}
pages(size: 5) {
title
}
}
}

If you are using the default theme or the Chocolatine theme, the search bar should now be visible.

tip

In case of emergency, Front-Commerce provides a configuration to quickly deactivate Attraqt's search feature. Use the FRONT_COMMERCE_ATTRAQT_DISABLED=true and restart your application to temporarily deactivate the module.

Add contextual information to your queries

Since version 2.23

Front-Commerce allows you to leverage Attraqt's Context feature in your application. This is a great way to add contextual information to your queries, so that you can get results adapted to your users needs.

Contexts can be provided at different levels, from the most generic to the most specific. Context values will be used as Attraqt context variables. Here's how to do it in your application.

Global context

The simplest way to add context variables to all your queries is to use a global context. Front-Commerce's Attraqt module has a configuration for it: config.attraqt.globalContext. It is defined in the Attraqt configuration provider, so you can use any extension mechanism at your disposal to customize this value.

Example: an app-wide context for every users and queries

import configService from "server/core/config/configService";

const myAppConfigProvider = {
name: "myAppConfig",
values: Promise.resolve({
attraqt: {
globalContext: {
source: "storefront",
version: "1.0.0",
},
},
}),
};

configService.insertAfter("Attraqt", myAppConfigProvider);

Example: a global context dynamically determined per request

import mem from "mem";
import configService from "server/core/config/configService";

const getContextFromShopId = mem((shopId) => {
return {
attraqt: {
globalContext: {
source: `storefront_${shopId}`,
// […] more compute intensive variables here
}
},
};
});

const myAppConfigProvider = {
name: "myAppConfig",
slowValuesOnEachRequest: (_req, config) => {
return getContextFromShopId(config.currentShopId);
};
};

configService.insertAfter("Attraqt", myAppConfigProvider);

You can also use remote values or per user values using other configuration providers features.

Layer-specific context

Contexts can also be provided at the layer level. It allows to add context variables only for search queries restricted to a single item kind (e.g: categories).

To do so, you must use the context option of datasource.buildLayer() function in your application. Example:

const layer = searchDatasource.buildLayer({
type: "categories",
// your context variables here
context: {
priority: "online_sales",
foo: "bar",
},
executeQuery: executeCategoryQuery,
formatHit: searchDatasource.formatters.category,
fetchErrorFallback: () => () => {
return Promise.reject();
},
});
info

Layer-specific context replace the global context.

Query-specific context

Finally, you can also implement advanced use cases by adding contextual information directly in the SearchQuery. It means that any scope, pagination or facet can update a query context.

To do so, you must use the addContext method of SearchQuery. Example: a context based implementation of random sorting could be implemented like this

const randomizable =
() =>
({ random = false }) => {
return (searchQuery) => {
if (random) {
searchQuery.addContext({ randomSort: true });
}
return searchQuery;
};
};

export default randomizable;
info

Query-specific context is merged with global/layer-specific context variables. It can override specific variables while keeping others unchanged.

Attraqt recommendations

Since version 2.19

Front-Commerce provides a loader to retrieve recommendations from Attraqt's Widgets.

Front-Commerce configuration

To enable the Attraqt recommendation module, you need to add it to your .front-commerce.js config:

.front-commerce.js
module.exports = {
modules: ["./node_modules/front-commerce/modules/recommendations-attraqt"],
serverModules: [
{ name: "FrontCommerce", path: "server/modules/front-commerce" },
{
name: "AttraqtRecommendations",
path: "recommendations-attraqt/server/modules/attraqt-recommendations",
},
{ name: "Magento2", path: "server/modules/magento2" },
],
webModules: [
{ name: "FrontCommerce", path: "./src/web" },
{
name: "AttraqtRecommendation",
path: "front-commerce/modules/recommendations-attraqt/web",
},
],
};

Then, you need to define the API url in your environment variables:

.env
FRONT_COMMERCE_ATTRAQT_RECOMMENDATION_API_URL=http://api.early-birds.io/widget

Attraqt Recommendations usage example

In this example, we'll make a module SuggestedProduct that fetches a recommendation from Attraqt via Front-Commerce's loader.

note

See Extend the GraphQL schema for instructions on how to add your own GraphQL module.

Front-Commerce exposes a GraphQL interface to simplify the process of fetching recommendations. You will first need to update your GraphQL schema to implement this interface and use it in a query:

my-module/server/modules/SuggestedProducts/schema.gql
type ProductRecommendation implements AttraqtRecommendationResult {
id: ID!
products: [Product]
}

input ProductRecommendationInput {
profileId: String
}

extend type Query {
productRecommendation(
input: ProductRecommendationInput
): ProductRecommendation
}

Add a resolver for this query:

my-module/server/modules/SuggestedProducts/resolvers.js
export default {
Query: {
productRecommendation: async (_, { profileId }, { loaders }) => {
return loaders.AttraqtRecommendations.loadRecommendationsForWidget(
"my-widget-id",
null,
profileId // Available since 2.28
);
},
},
ProductRecommendation: {
products: async (recommendation, _, { loaders }) => {
// Note: the shape of recommendation.recommendations will vary
// depending on your data indexed in Attraqt. Adapt this example to your use case.
const skus = recommendation.recommendations
.map(({ id }) => id)
.filter(Boolean);
return loaders.Product.loadBySkus(skus);
},
},
};

On the front-end side, retrieve the results from this query using the GraphQL fragment provided by Front-Commerce:

my-module/web/theme/modules/SuggestedProducts/SuggestedProductsQuery.gql
#import "theme/modules/AttraqtRecommendations/AttraqtRecommendationResultFragment.gql"
#import "theme/pages/Product/ProductFragment.gql"

query SuggestedProductsQuery($input: ProductRecommendationInput) {
productRecommendation(input: $input) {
...AttraqtRecommendationResultFragment
products {
...ProductFragment
}
}
}

You can now use it in a component:

my-module/web/theme/modules/SuggestedProducts/SuggestedProducts.js
import React from "react";
import { graphql } from "react-apollo";
import SuggestedProductsQuery from "./SuggestedProductsQuery.gql";

const SuggestedProducts = ({ recommendation }) => {
return <>{/* ... Display products */}</>;
};

export default graphql(SuggestedProductsQuery, {
options: (props) => {
/*
* `profileId` is only used of Personalised Recommendations.
* See: https://attraqt.gitbook.io/developer-documentation/xo-recommendations/using-the-recommendations-api#personalised-recommendation
*
* The best way to retrieve the customer's profileId might vary depending on your use case.
* See with your Attraqt representative the best way to retrieve it for your use case.
*/
const profileId = getAttraqtProfileId();
return {
variables: {
input: {
profileId,
},
},
};
},
props: ({ data }) => {
return {
recommendation: data.loading ? null : data.productRecommendation,
};
},
})(SuggestedProducts);
caution

If you are using XO Recommendations API with Attraqt Activity pipeline, the profileId will be must be prefixed with "sessionid/", like so:

const prefixedProfileId = "sessionid/" + profileId;
info

Please note that this example is only one way of retrieving recommendations from Attraqt Recommendations API. A better solution could be implemented depending on your use case.

Using Attraqt Orchestrator Chrome extension

In order to use the Attraqt Orchestrator extension for Google Chrome, Front-Commerce provides a front-end component which does the needed setup. Given the example above, you will need to update your front-end component, and use it to initialize Attraqt Orchestrator:

my-module/web/theme/modules/SuggestedProducts/SuggestedProducts.js
import React from "react";
import AttraqtRecommendationChromeExtensionRegisterer from "theme/modules/AttraqtRecommendations/attraqtRecommendationChromeExtensionRegisterer.js";
import { graphql } from "react-apollo";
import SuggestedProductsQuery from "./SuggestedProductsQuery.gql";

const SuggestedProducts = ({ recommendation }) => {
return (
<>
<AttraqtRecommendationChromeExtensionRegisterer
recommendation={recommendation}
/>
{/* ... Display products */}
</>
);
};

// ...

With this change, Attraqt's Chrome extension should be initialized correctly when accessing the page were SuggestedProducts is used.

Since version 2.15

If no search module is configured Front-Commerce will default to using the native Magento search API to do the search.

native Magento search API uses the price without tax value to achieve its price filtering capabilities. This is not what customers typically expect. To overcome this you need to set FRONT_COMMERCE_MAGENTO_SEARCH_TAX_RATE to the expected tax rate on your site. Please note this may not work for all scenarios as you may have different tax rates depending on country. So we recommend you use the tax rate that most applies to your customers.