Skip to main content
Version: 2.x

Search engine

When configured with Magento1 , 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:

Front-Commerce supports browsing products using the native Magento API for category listing pages. Please contact us if your store uses a custom Magento search implementation to see how to make it work in your Front-Commerce project.

Elasticsearch

Requirements

On Magento's side, you need to install the front-commerce-oss/magento1-elasticsuite-indexer module. You can install it with composer:

composer require front-commerce-oss/magento1-elasticsuite-indexer

After the installation, you need to configure it, at least:

  1. in System > Catalog > Catalog in the Catalog Search section, make sure the search engine is set on Smile Searchandising Suite
  2. in the same section, set the server host and port
  3. take note of the alias (magento by default)

You can then run the indexer so that the products, categories and cms pages are indexed in Elasticsearch.

Front-Commerce configuration

First, you need to make sure the Elasticsearch search client is installed with a version that matches your ElasticSearch server:

npm i @elastic/elasticsearch@6

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

.front-commerce.js
-  modules: [],
+ modules: ["./node_modules/front-commerce/modules/datasource-elasticsearch"],
serverModules: [
{ name: "FrontCommerce", path: "server/modules/front-commerce" },
+ {
+ name: "Magento1Elasticsearch",
+ path: "datasource-elasticsearch/server/modules/magento1-elasticsearch",
+ },
{ name: "Magento1", path: "server/modules/magento1" },
]
Known issue

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

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

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

query Search {
search(query: "whatever you want to search for") {
query
products(params: { from: 0, size: 5 }) {
total
products {
sku
name
}
}
}
}

If you are using the default theme or the theme Chocolatine, 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

Requirements

On Magento's side, you need to install the algolia/algoliasearch-magento module. You can install it with modman:

modman clone https://github.com/algolia/algoliasearch-magento.git

After the installation, you need to configure it, at least:

  1. in System > Algolia Search > Configuration in the Credentials & Setup section, set the Enable Indexing option
  2. in the same section, fill the credentials you can find on the Algolia Dashboard
  3. The attribute category_ids must be listed in both the facets configuration and in the indexed product attributes (and there it must be set as Searchable) as Front-Commerce relies on it to list the products in categories.

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

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
-  modules: [],
+ modules: ["./node_modules/front-commerce/modules/datasource-algolia"],
serverModules: [
{ name: "FrontCommerce", path: "server/modules/front-commerce" },
+ {
+ name: "Magento1Algolia",
+ path: "datasource-algolia/server/modules/magento1-algolia",
+ },
{ name: "Magento1", path: "server/modules/magento1" },
]
Known issue

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

As of Front-Commerce 2.6, Algolia's module is automatically configured. If you are using Front-Commerce 2.5, you need to define all the Algolia related environment variables in your .env file.

Front-Commerce 2.6 takes the following parameters from Magento:

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

caution

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:

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
}
}
}
info

Support for category or page search with Algolia has been added in Front-Commerce 2.13.

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

Attraqt

Since version 2.27

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: "Magento1Attraqt",
path: "datasource-attraqt/server/modules/magento1-attraqt",
},
{ name: "Magento1", path: "server/modules/magento1" },
],
};
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

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: "Magento1", path: "server/modules/magento1" },
],
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.