We learned about how you can setup Sitecore Search and preparing your widgets in this blog but we want to know how we can use your widgets to create Sitecore renderings and integrate them in it. Another requirement we would like to have is automatically get a list of related content based on the page you are on, this usually happens when you’re on a blog or article page and you would want to automatically get some related pages on the bottom of your page.
We have an example below where we have a blog article and we want three related blogs to be featured at the bottom. Using Sitecore Search and the widgets available we can easily implement this.
Setting Up Your Component
I won’t put too much details but we will need to get all the required things in order to get a Sitecore Rendering. We
need the template in place as well as the JSON Rendering. Let’s call this component as
RelatedContent. We then create our RelatedContent.tsx file inside the
components
folder. The code below is a good example of how you would want to setup your component. We
can go step by step and I’ll explain each part and it’s importance.
import { Field } from '@sitecore-jss/sitecore-jss-nextjs';
import React from 'react';
import { ComponentProps } from 'lib/component-props';
import { Environment, WidgetsProvider } from '@sitecore-search/react';
import RelatedPages from 'widgets/RelatedPages/index';
import config from 'temp/config';
type Fields = {
heading?: Field<string>;
};
type RelatedContentProps= ComponentProps & {
fields: Fields;
};
export const Default = ({ fields }: RelatedContentProps) => {
const SEARCH_ENV = config?.searchEnv as Environment;
const SEARCH_CUSTOMER_KEY = config?.searchCustomerKey;
const SEARCH_API_KEY = config?.searchApiKey;
return (
<div>
<WidgetsProvider
env={SEARCH_ENV}
customerKey={SEARCH_CUSTOMER_KEY}
apiKey={SEARCH_API_KEY}
publicSuffix={true}
>
<RelatedPages rfkId="rfkid_x" defaultKeyphrase={fields?.heading?.value ?? ''}></RelatedPages>
</WidgetsProvider>
</div>
);
};
Make sure you keep your keys safe and private, I’ve configured it to be added on the temporary config file. I’ll leave it to you if you have a preference on how you handle your API Keys, these are the private data that will be needed to connect to Sitecore Search.
const SEARCH_ENV = config?.searchEnv as Environment;
const SEARCH_CUSTOMER_KEY = config?.searchCustomerKey;
const SEARCH_API_KEY = config?.searchApiKey;
You will also need to wrap your widget with the Sitecore Search’s WidgetsProvider
. Don’t forget to grab
the rfkId
from the widget you created in https://cec.sitecorecloud.io/. In our example we created a
RelatedPages widget which we are basing off a key phrase with the value being the heading of the
page. Below you will see the RelatedPagesComponent widget code.
import { WidgetDataType, useSearchResults, widget } from '@sitecore-search/react';
import { ArticleCardStyled } from './styled';
import PropTypes from 'prop-types';
export const RelatedPagesComponent = ({ defaultKeyphrase = '', defaultItemsPerPage = 3 }) => {
const language = 'en';
const {
widgetRef,
queryResult: { data: { total_item: totalItems = 0, content: articles = [] } = {} },
} = useSearchResults({
query: (query) => {
query.getRequest();
},
state: {
itemsPerPage: defaultItemsPerPage,
keyphrase: defaultKeyphrase,
},
});
return (
{totalItems > 0 && (
<div ref={widgetRef}>
{articles.map((a) => (
<ArticleCardStyled.Root
className="card flex flex-col overflow-hidden rounded-1"
key={${<span class="hljs-attr">a.id</span>}@${<span class="hljs-attr">a.source_id</span>}@${<span class="hljs-attr">language</span>}
}
>
<ArticleCardStyled.Title className="mb-4">{a.title}</ArticleCardStyled.Title>
</ArticleCardStyled.Root>
))}
</div>
)}
);
};
RelatedPagesComponent.propTypes = {
defaultItemsPerPage: PropTypes.number,
defaultKeyphrase: PropTypes.string,
};
const RelatedResults = widget(RelatedPagesComponent, WidgetDataType.SEARCH_RESULTS, 'content');
export default RelatedResults;
The strategy we are looking at here is using useSearchResults instead of useRecommendations since we want results based on a specific criteria of the page and not the user.
const {
widgetRef,
queryResult: { data: { total_item: totalItems = 0, content: articles = [] } = {} },
} = useSearchResults({
query: (query) => {
query.getRequest();
},
state: {
itemsPerPage: defaultItemsPerPage,
keyphrase: defaultKeyphrase,
},
});
We then need to setup this component as being a widget.
const RelatedResults = widget(
RelatedPagesComponent,
WidgetDataType.SEARCH_RESULTS,
'content'
);
We use the widget
function with needs at least 3 arguments. First would be the component itself, next is
based on what hook we are using here are a couple of examples of the data type.
WidgetDataType.SEARCH_RESULTS
WidgetDataType.PREVIEW_SEARCH
WidgetDataType.RECOMMENDATION
Then most of the time you’ll just need to pass the string content
.
Leveraging Sitecore Search for Enhanced XM Cloud Development
We have gone over a good example of what other ways we can use the Sitecore Search Widget and how easily you can integrate it into one of your Sitecore Renderings. There are more ways you can integrate Sitecore Search into your headless XM Cloud project and push your development further. We’ll dive more into different ways and details on other widgets like Preview Search and maybe even Recommendations in the future.