Query API

Website personalisation: JavaScript integration

APIs for querying and retrieving data.

Reference

See the options and parameters available within our query API.

<div id="Results"><!-- Results from Ometria will be placed here --></div>

<script>
$g.load({
    template        : { id: "{{ cat_or_search }}", target: "#Results" }, // required (Object)
    page_context    : { /* parameters */ }, // optional (Object),
    args            : { /* parameters */ }, // optional (Object or Function),
    init            : function(response) { /* custom actions */ } // optional (Function)
    success         : function() { /* custom actions */ } // optional (Function)
});
</script>

template

Required.

An object that takes two parameters:

  • id (Required) - The id of the required template, usually category or search.
  • target (Required) - This is a CSS selector defining the DOM element within which the results will be placed.
<div class="ometria_content"><!-- Results from Ometria will be placed here --></div>
<script>
$g.load({
   template        : { id: "search", target: "ometria_content" },
   success         : function(response) { /* process results */  }
});
</script>

page_context

Optional.

An object defining various details about the current page.

These include:

  • category_id (Required) - The id of the category for the current page.
  • language_id (Optional) - This is only required if multiple languages are defined.
  • currency_id (Optional) - This is only required if multiple currencies are defined.
  • warehouse_id (Optional) - This is only required if you have multiple warehouses and would like the stock data to reflect one specific warehouse rather than the sum of all of them.
<div id="Results"><!-- Results from Ometria will be placed here --></div>
<script>
$g.load({
   template        : { id: "category", target: "#Results" },
   page_context    : { category_id: "10038", language_id: "de-de", currency_id: "EUR", warehouse_id: "Lon" }
});
</script>

args

Optional.

An object or function defining custom parameters.

These custom parameters are typically dynamic pieces of information that can be used as triggers in Ometria's website personalisation feature.

<div id="Results"><!-- Results from ometria will be placed here --></div>
<script>
$g.load({
   template        : { id: "category", target: "#Results" },
   args            : { geo_country: "US", geo_state: "AK", weather: "snowing" }
});
</script>

init

Optional.

A callback function which can be used before the response is requested.

In the example below the callback function will initialise the UI preparation for loading content:

<div id="Results"><!-- Results from Ometria will be placed here --></div>
<script>
$g.load({
   template        : { id: "category", target: "#Results" },
   page_context    : { category_id: "10038", language_id: "de-de", currency_id: "EUR" },
   init            : function() {
       // show loading before grabbing content
       document.querySelector("#Results").innerHTML = "Loading, please wait...";
   }
});
</script>

success

Required.

A callback function used to process the response.

The callback function receives a response variable which contains the JSON response from the Query API.

In the example below the callback function will insert HTML generated by the Query API and insert into two container elements:

<div id="Results"><!-- Results from Ometria will be placed here --></div>
<script>
$g.load({
   template        : { id: "category", target: "#Results" },
   page_context    : { category_id: "dresses", language_id: "en-us", currency_id: "USD" },
   success         : function(response) {
       // bind custom events to new content
       document.querySelectorAll("#Results .add-to-basket").forEach(function(btn) {
           btn.addEventListener("click", function() {
               alert("add to basket has been clicked");
           });
       });
   }
});
</script>

Templates vs. elements

You need to decide whether to use templates or elements.

👍

Our recommendation

A standard approach is to request a template for the category and search pages, but to request elements for all other pages.

Templates

An Ometria onsite template can contain placeholders for elements.

In this example we only call a template, which will return a single html fragment:

<script>
$g.load({
   template        : { id: "category", target: "#Results" },
   page_context    : { category_id: "coats" }
});
</script>

Demonstrated in this image, the template is made up of many individual parts, in particular elements, but returns all of the results in a single html fragment (the green overlay):

Elements

Elements are the smallest logical components for data.

Each element contains a list of products and each element can have different strategies and show different products.

When a query for an element is made, it can be returned as either a small HTML fragment, or a JSON representation of the data.

In this example the page requires three sets of products, so three elements are requested:

<script>
$g.load({
   elements        : [
                       { id: "category", target: "#cat" },
                       { id: "plp_recs_left", target: "#left" },
                       { id: "plp_recs_bottom", target: "#bottom" }
                   ],
   page_context    : { category_id: "dresses" }
});
</script>

Unlike calling a template, when you request elements you get an individual html fragment for each element, allowing you to inject the separate html fragments individually:

Query API Examples

Here's a quick guide for adding different types of content to different pages.

The approach for each page is the same, but each example demonstrates asking for different types of content on different types of pages.

Homepage recommendations

Adding two recommendation elements to the home page:

<div class="recs1"><!-- Results from Ometria will be placed here --></div>
<div class="recs2"><!-- Results from Ometria will be placed here --></div>
<script>
$g.load({
   page_context    : { category_id: "$" },
   elements        : [
       { id: "home_page_recs_1", target: ".recs1" },
       { id: "home_page_recs_2", target: ".recs2" }
   ]
});
</script>

Category/Collection Page

Get products for the main set of product results on a category/collection page:

<div id="Results"><!-- Results from ometria will be placed here --></div>
<script>
$g.load({
   template        : { id: "category", target: "#Results" },
   page_context    : { category_id: "new-in" }
});
</script>

Search

Populate the search page.

📘

Note

By using the template "search", null results and no search term templates will automatically display. These can include merchandised elements if desired.

<div id="Results"><!-- Results from Ometria will be placed here --></div>
<script>
$g.load({
   template        : { id: "search", target: "#Results" },
   page_context    : { search_text: "jeans" }
});
</script>

Product details page

Retrieving two recommendations.

<div id="recs1"><!-- Results from Ometria will be placed here --></div>
<div id="recs2"><!-- Results from Ometria will be placed here --></div>
<script>
$g.load({
   page_context    : { category_id: "sale", product_id: "49801" },
   elements        : [
       { id: "pdp_recs_1", target: "#recs1" },
       { id: "pdp_recs_2", target: "#recs2" }
   ]
});
</script>

Advanced Query API

This section contains a list of advanced features.

📘

JSON

If you want Ometria to return JSON rather than HTML then the JSON Query API is the recommended approach.

If you want Ometria to return HTML then we recommend the standard Query API.

JSON Query API Reference

In most cases we recommend using the load API call, however in some cases you may need to use JSON API to get the JSON response directly.

Here are the options and parameters available within our JSON query API.

<script>
$g.json({
    template            : "{{ template }}", // optional (String)
    elements            : [ "{{ element_1 }}", "{{ element_2 }}"], // optional (Array)
    page_context        : { /* parameters */ }, // optional (Object),
    args                : { /* parameters */ }, // optional (Object or Function),
    is_paging_request   : false, // optional (Boolean)
    response_options    : { /* parameters */ } // optional (Object)
}).then((data) => {
    // process request
    console.log("ometria request data", data);
});
</script>

template

Optional.

A string defining the template to run.

The value you assign depends on the type of page being delivered.

Although there are multiple templates, in practice you will normally only use a template for category and search pages.

See also: Templates vs. elements

<script>
$g.json({
   template        : "search"
}).then((data) => {
   console.log("ometria request data", data);
});
</script>

elements

Optional.

An array with a list of element identifiers.

Each element identifier must correspond to those elements defined in the Ometria onsite feature.

It is possible to request both a template and a list of elements, however, in practice you would typically use one method or the other.

<script>
$g.json({
   elements        : ["home_recs_1", "home_recs_2"]
}).then((data) => {
   console.log("ometri request data", data);
});
</script>

page_context

Optional.

An object defining various details about the current page.

These include:

  • page_url (Optional): Only required if you wish to override the actual page URL.
  • category_id (Optional): Only required if category specific data is required, e.g. category pages.
  • product_id (Optional): Only required if product specific data is required, e.g. product detail pages.
  • language_id (Optional): This is only required if multiple languages are defined.
  • currency_id (Optional): This is only required if multiple currencies are defined.

In most cases you won't need to supply the page_url as it is calculated automatically.

However, if you want to override this value for any reason then in that case you can assign a page_url value.

<script>
$g.json({
   template        : "category",
   page_context    : {
       page_url        : "https://mysite.com/dresses"
       category_id     : "dresses",
       product_id      : "abc_123".
       language_id     : "es-es",
       currency_id     : "EUR"
   }
}).then((data) => {
   console.log("ometria request data", data);
});
</script>

args

Optional.

An object or function defining custom parameters.

These custom parameters are typically dynamic pieces of information that can be used as triggers in the Ometria website personalisation feature.

<script>
$g.json({
   template        : "category",
   args            : {
       geo_country     : "US",
       geo_state       : "AK",
       weather         : "snowing"
   }
}).then((data) => {
   console.log("ometria request data", data);
});
</script>

is_paging_request

Optional.

A boolean value.

If set to true then facets will be omitted from the response.

This is useful for optimising paging requests where the facets have already been rendered.

If no is_paging_request value is sent, then the field defaults to "false".

<script>
$g.json({
   template            : "category",
   is_paging_request   : true
}).then((data) => {
   console.log("ometria request data", data);
});
</script>

response_options

Optional.

A object with a set of fields used to control the response payload.

If set to true then facets will be omitted from the response.

This is useful for optimising paging requests where the facets have already been rendered.

<script>
$g.json({
   template            : "category",
   response_options    : {
       fields: {
           /*
           List of fields available for products, only include the fields you need
           */
           products: [
               "id",
               "sku",
               "stock",
               "slug",
               "url",
               "titles",
               "abstracts",
               "media",
               "pricing",
               "features",
               "variants",
               "properties",
               "tags"
           ],
           /*
           If "features" ARE included in list of fields above, then you can use "product_features" to return only a subset of all available features
           By default, if product_features is not defined, then ALL features will be returned
           */
           product_features: [
               "vendor"
           ],
           /*
           If variants ARE included in the list of fields above, then you can use the depth to define how deep into the variant to return data.
           For example, if variants are COLOUR x SIZE but you only need colours for the UI then use "depth": 1. If you also need the sizes then "depth": 2
           By default, if product_variants is not defined then ometria will return ALL variants to the full depth
           */
           product_variants: {
               "depth": 1
           }
       }
   }
}).then((data) => {
   console.log("Ometria request data", data);
});

</script>

Advanced JSON Query API Examples

Here is a quick guide for adding different types of content to different pages.

The approach for each page is the same but the examples below show asking for different types of content on different types of pages.

Simple homepage recommendations

In this example we add two recommendation elements to the home page:

<script>
$g.json({
   elements: ["home_page_recs_1", "home_page_recs_2"]
}).then((data) => {
   const recs1 = data.elements.home_page_recs_1;
   const recs2 = data.elements.home_page_recs_2;
   // buildTemplate(recs1)
   // buildTemplate(recs2)
});
</script>

Simple category/collection page

Get a set of product results on a category/collection page:

<script>
$g.json({
   template        : "category",
   page_context    : {
       category_id     : "coats",
       language_id     : "en-us",
       currency_id     : "USD"
   }
}).then((data) => {
   const category_data = data.elements.category;
   // buildTemplate(category_data)
});
</script>

Simple search

Populate the search page.

📘

Note

By using the template "search", null results and no search term templates will automatically display. These can include merchandised elements if desired.

<script>
$g.json({
   template: "search"
}).then((data) => {
   const search_data = data.elements.search;
   // buildTemplate(search_data)
});
</script>

Product detail page

In these examples we are retrieving two recommendations.

📘

Note

When making a request for product recommendations, category_id and product_id are normally required.

<script>
$g.json({
   elements        : ["pdp_recs_1", "pdp_recs_2"],
   page_context    : {
       category_id     : "dresses",
       product_id      : "abcxyz"
   }
}).then((data) => {
   const search_data = data.elements.search;
   // buildTemplate(search_data)
});
</script>

async/await

You can use the async/await pattern rather than the promise pattern if you like.

<script>
async function getCategoryData() {
   let data = await $g.json({
       template        : "category",
       page_context    : {
           category_id     : "coats",
           language_id     : "en-us",
           currency_id     : "USD"
       }
   });
   const category_data = data.elements.category;
   // buildTemplate(category_data)
}
getCategoryData();
</script>

Advanced category/collection page

Use advanced options to control the query request and response for a category/collection page.

In this example a paging request is being made, args are being passed and the response fields are being defined.

📘

Note

For pagination pg=x controls the page to display and ps=y determines the page size.

The default page size is set by the merchandiser in the console but if you have, for example, a dropdown to allow the customer to change page size the ps= is the way to go.


Advanced Query API Fetch

Reference

In most cases we recommend using the load API call, however in some cases you may need to use Fetch, which is a lower level API call:

<script>
$g.fetch({
   request_id      : "{{ request_id }}", // optional (String or Number)
   format          : "{{ html_or_json }}", // optional (String), default: "html"
   template        : "{{ template }}", // optional (String)
   elements        : [ "{{ element_1 }}", "{{ element_2 }}"], // optional (Array)
   page_context    : { /* parameters */ }, // optional (Object),
   args            : { /* parameters */ }, // optional (Object or Function),
   success         : function(response) { /* custom actions */ } // required (Function)
});
</script>

request_id

Optional.

A string or number containing a unique identifier.

This is an optional value you provide to the API.

The API will return this value back with the response.

format

Optional.

A string defining the format of the content returned.

Permitted values are html or json. If format is not specified then a default value of html is used.

template

Optional.

A string defining the template to run.

The value you assign depends on the type of page being delivered.

Permitted values are:

  • home
  • category
  • search
  • product
  • information

📘

Note

Though there are multiple templates, in practice you will normally only use a template for category and search pages.

See: Templates vs. elements

<script>
$g.fetch({
   format          : "json",
   template        : "search",
   success         : function(response) { /* process results */  }
});
</script>

elements

Optional.

An array with a list of element identifiers.

Each element identifier must correspond to those elements defined in Ometria's website personalisation feature.

📘

Note

It is possible to request both a template and a list of elements, however, in practice you would typically use one method or the other.

page_context

Optional.

An object defining various details about the current page.

These include:

  • category_id (Optional) - Only required if you want to make the autocomplete category specific.
  • language_id (Optional) - Only required if multiple languages are defined.
  • currency_id (Optional) - Only required if multiple currencies are defined.

args

Optional.

An object or function defining custom parameters.

These custom parameters are typically dynamic pieces of information that can be used as triggers in Ometria's website personalisation feature.

success

Required.

A callback function which you will use to process the response.

The callback function will receive a response variable which will contain the JSON response from the Query API.

In the example below the callback function will insert HTML generated by the Query API and insert into two container elements:

<script>
// get JSON
$g.fetch({
    format          : "json",
    elements        : ["home_page_recs_1", "home_page_recs_2"],
    success         : function(response) {
        const recs1 = response.elements.home_page_recs_1;
        const recs2 = response.elements.home_page_recs_2;
        // buildTemplate(recs1)
        // buildTemplate(recs2)
    },
});
</script>
<script>
// get HTML
$g.fetch({
    format          : "html",
    elements        : ["home_page_recs_1", "home_page_recs_2"],
    success         : function(response) {
        const recs1 = response.elements.home_page_recs_1;
        const recs2 = response.elements.home_page_recs_2;
        if (recs1 && recs1.html) {
            document.getElementById("Recs1").innerHTML = recs1.html;
        }
        if (recs2 && recs2.html) {
            document.getElementById("Recs2").innerHTML = recs2.html;
        }
    },
});
</script>

Advanced JSON query fetch examples

This is a quick guide for adding different types of content to different pages.

The approach for each page is the same, but the examples show asking for different types of content on different types of pages.

Homepage recommendations

In this example we add two recommendation elements to the home page:

<script>
$g.fetch({
   format          : "json",
   elements        : ["home_page_recs_1", "home_page_recs_2"],
   success         : function(response) {
       const recs1 = response.elements.home_page_recs_1;
       const recs2 = response.elements.home_page_recs_2;
       // buildTemplate(recs1)
       // buildTemplate(recs2)
   },
});
</script>

Category/Collection Page

Get products for the main set of product results on a category/collection page:

<script>
$g.fetch({
   template        : "category",
   success         : function(response) {
       document.querySelector("element_selector").innerHTML = response.templates.category.html;
   }
});
</script>

Search

Populate the search page.

📘

Note

By using the template "search", null results and no search term templates will automatically display. These can include merchandised elements if desired.

<script>
$g.fetch({
   template        : "search",
   success         : function(response) {
       document.querySelector("element_selector").innerHTML = response.templates.category.html;
   }
});
</script>