Skip to main content

Content Search and Content Recommendations

Dan Macarie avatar
Written by Dan Macarie
Updated over a week ago

Content Search and Content Recommendations - FAQ Page

Introduction

Content Search can be used by your users to search through and find the most relevant blog posts, how-to videos, recipes and more. It can be a powerful tool to complement your product / SKU search experience and marry content with commerce.

Separately, Content Recommendations can be used to provide personalized and context dependent content suggestions on Homepage, PLPs, PDPs or other page types. For example if you are a DIY brand, if a customer has shopped for gardening supplies, they might be served relevant blog post on gardening. You can also show content ‘most viewed’ lists or ‘viewed together’ recommendations.

Nosto uses keyword search and vector search to find content that matches the query of the user.

Examples of Content Search

Examples of Content Recommendations

Indexation of Content Data

Nosto can index various content types using its customizable ‘product’ object. The ‘product’ object serves as a metaobject within the Nosto data structure and is designed for flexible use. It can be configured to take in any data type such as blog posts, video (meta data), recipes and more.

Once you have indexed any content, the content will appear in the Product Intelligence feature that can be found when navigating to the Experience.ai dropdown.

As a rule of thumb: Nosto only needs to index lightweight meta data of your content such as title, description or tags. Kindly be mindful that payload size limits are in place.

All Platforms

To index content, metadata about the content can be sent to Nosto using the product schema found here. It can be passed via tagging or various API methods. Kindly make sure that the content data is passed through to Nosto the same way as your catalog data.

At a minimum Nosto needs to have the above data provided, or otherwise the data will be dropped. This includes product_id, name, url, image_url, availability set to instock and a minimum price of at least 1.

Since you are indexing an object that is not a SKU/product, you have to let Nosto know what type of content is being indexed. This will be crucial later to break out content on the presentation layer compared to SKU search results.

Nosto recommends using the tag 1 or 2 field or custom fields key:value pairs to share the content type with Nosto.

We recommend including the tagging of a relevant image that contains information that matches the entry being indexed. You can also decide to pass additional data such as the blog content to Nosto. This would allow for searching via keyword search through said blog post.

Shopify

More often than not, Shopify merchants store content as Metaobjects.

To index content that lives within Shopify Metaobjects for Nosto, you must first turn them into products programmatically. To accomplish this you need to use the metaobject as a source of structured data and then create a product using that data using the Admin GraphQL API.

  1. Retrieve the Metaobject: First, fetch the metaobject and its fields. This gives you the data you want to use for your product.

  2. Create a Product Using Metaobject Data: Use the data from the metaobject to populate the fields of a new product. You can use the productCreate or productSet mutation.

A similar approach can be used for blog posts that live within Shopify.

  1. Retrieve Blog Post Data: Use the Shopify Admin API to fetch the blog post content, including title, body, images, and any metadata.

  2. Map Blog Content to Product Fields: Extract relevant information from the blog post to populate product fields such as product title, description, images, and tags.

  3. Create Product via API: Use the Shopify Admin API's product creation endpoint to create a new product with the mapped data. This product can serve as a placeholder.

  4. Automate the Process: Optionally, set up a webhook or scheduled job to automate creating or updating placeholder products when blog posts are created or updated.

The above described rules on availability and price need to be respected for Nosto to index the object.

Presentation of Content

With the content indexed, let’s now look at breaking out the content results from the product results. In the below examples, we assume the custom fields were used to tag ‘blog post’ as a content type.

Autocomplete

To display articles within the autocomplete's suggested content, ensure they are integrated into your Nosto product catalog and properly tagged. This tagging, through a custom tag or field, enables their recognition as articles.

Once integrated, you can differentiate between products and articles directly within the Autocomplete component using basic JSX, by filtering through a custom field or custom tag. Let’s say that in your catalogue the products and articles will have a custom field called contentType and that for products the value of that field is product whereas for articles it is going to be article

It's important to note that this solution filters data on the frontend rather than receiving pre-filtered results from the API. Consequently, some adjustments are required. Begin by modifying the index.js file of your Search template to ensure sufficient data is received on the frontend, by changing size: defaultConfig.autocompleteProductsSize into size: defaultConfig.autocompleteProductsSize presuming 100 is enough to have a good amount of articles and products

autocompleteQuery: {
products: {
fields: [
"productId",
// add here all your fields
],
size: 100 // I guess 100 products/articles are enough to show something relevant
},

At this point, you can leverage basic JavaScript methods to filter all the products that have the custom field contentType marked as article

{products?.hits
?.filter(hit =>
hit.customFields?.some(field =>
field.key === "contentType" && field.value === "article"
)
)
?.slice(0, 10)
?.map(hit => {
return (
<a class="article-link" url={hit.url}> {hit.name} </a>
)
})}

This method allows you to filter for articles and display them using a custom ArticleLink component, which directs users to the respective article pages.

And now, to display only products, you can apply the opposite filtering logic and utilize the Nosto Autocomplete component.

{products?.hits
?.filter(hit =>
hit.customFields?.some(field =>
field.key === "contentType" && field.value === "article"
)
)
?.slice(0, 10)
?.map(hit => {
return (
<AutocompleteElement key={hit.productId} hit={hit}> </AutocompleteElement>
)
})}

To ensure your Autocomplete UI remains consistent and free from disruption, it's recommended to limit the number of displayed products or articles. Utilize .slice(0, 5) when iterating through products/articles to cap the visible items at five. This prevents products?.hits from containing an excessive number of items, even after initial filtering.

Search Engine Results Pages (SERP)

Now that the articles and products are shown in the autocomplete modal, it is time to take care of the search engine results’ page (SERP), should you want to show articles on there as well.

Unlike with the autocomplete, doing this in the SERP heavily relies on your implementation and data structure, and there is no one-size-fits-all-solution.

I will be proposing to you some different solutions based on possible scenarios, also naming a few hiccups you may find along the way.

Products vs Articles in the facets

The best approach here would be to show products and articles within the same SERP, and then filter them using the Nosto facets: for example, you can create a boolean facet based on whether a product is also an article or not, leveraging e.g. on the product’s custom tag.

In this way you can give your user the chance to show only articles or only products.

Tab for selecting Articles or Products

A more visually refined approach would be to create a custom component which is basically tab buttons, like this

Which, by means of our custom Nosto Preact hooks, will filter products and articles alike.

The difference between this approach and the one above is that this latter one create a custom filter specifically for products/articles, whereas in the approach above this facet is among the other products’ facets (size, color, etc.)

Additional considerations

Whatever path you will decide to take, it is important to avoid directly filtering the products object (like we did for the autocomplete) in order to exclude some kind of items e.g. the articles or the products.

This is because the filtering operation happens with the frontend data, as opposed to happening with the data coming from the API.

With this I mean that if Nosto, after a search query, will send to frontend 50 products, but you will then filter them and they will be reduced to 20, the Search template will remember to have sent 50; in this case, components like the Pagination will be affected, as it will show that there are 2 pages of products to see, but after the filtering, the products will barely fill the first page.

Content Recommendations

To only show content in a given recommendation slot, you can navigate to the filter section during the edit flow of the recommendation.

Set a basic filter and then, depending on how the content type information has been passed to Nosto, select to include custom tags or custom field that includes said information.

You can also include advanced if-this-then-that filters.

Did this answer your question?