Create a Sitecore Next.js component with reuseable data
We previously created a content editable Sitecore Next.js component, whose data comes from the page item. However, sometimes we need to create components which can appear in multiple places. If a component appears in multiple pages, it would be tedious and a maintainence nightmare to enter the same data over and over for each page the component appears in.
This tutorial will guide you how to create a Sitecore Next.js component with reuseable data using a Sitecore concept known as datasources. The component we'll create is a Call To Action component.
Create a datasource template
We'll first start by creating the datasource template. This will be a template to hold data about a Call To Action.
- In the Content editor, create a CallToAction template folder
- Navigate to
/sitecore/templates/Feature
- right click, insert, Template folder
- enter
CallToAction
- Navigate to
- From the
CallToAction
template folder, create a template and name itCallToAction
- (optional) Give the template an icon
- Template section, name it
CallToAction
- Fields:
- Description - Rich Text
- Button Text - Single line text
Create datasource items
Once we have a CallToAction template, we can create the datasource items.
- On
/sitecore/content/XmNextJs
, create a folder to hold CallToAction items- right click, insert, Insert from template
- select
Folder
under /Templates/Common - give a name
CallToAction items
- This item will hold all of the CallToAction items that we're going to create
- On this folder item, configure
Insert Options
to include theCallToAction
template we previously created- Main ribbon, Configure, Insert Options
- Select
CallToAction
- Insert a
CallToAction
item under the "CallToAction items" folder- Name:
Learn nextjs
- Description:
Learn Next.js!
(feel free to put your own description) - Button Text:
Learn more!
- Name:
- Insert another
CallToAction
item under the "CallToAction items" folder- Name:
Learn Sitecore
- Description:
Learn Sitecore!
(feel free to put your own description) - Button Text:
Learn more!
- Name:
Create the rendering
- Navigate to
/sitecore/layout/Renderings/Feature
- Create a rendering folder and call it
CallToAction
- Create a Json Rendering underneath that and call it
CallToAction
as well - On this rendering, scroll down and set
- Datasource Location to
/sitecore/content/XmNextJs/CallToAction Items
- Datasource Template to
/sitecore/templates/Feature/CallToAction/CallToAction
- Datasource Location to
We see two new settings we have not set before:
- Datasource Location - where the datasource items are located
- Datasource Template - what template is compatible with the rendering
Update page rendering
- Go to the Placeholder Settings and add CallToAction to the
jss-main
placeholder - Navigate to Artile Route Standard Values
/sitecore/templates/Project/xmnextjs/Article Route/__Standard Values
- Presentation > Details > Shared Layout
- Add CallToAction to the
/jss-main
placeholder- also select "Open the Properties dialog box immediately."
- Under Data Source, click Browse Notice that it took us to the correct datasource node because of the Datasource Location that we've set. Also noticed that we are only allowed to add CallToAction items and not the folder because of the Datasource Template setting.
- Select
Learn Nextjs
- Click OK and save the item
- Publish all your changes
Verify the route data
To verify data about an article page, we will look at the data returned by the Sitecore Layout Service.
- In Visual Studio Code, look in
src/rendering/scjssconfig.json
and copy the apiKey value. - In a browser, open
https://cm.xmnextjs.localhost/sitecore/api/layout/render/jss?item=/my-first-article-page&sc_apikey={YOUR API KEY}&sc_mode=normal
Replace /my-first-article-page
with the URL to your actual article page
You should see something like below. If not, ensure you've published all items in Sitecore.
...
"placeholders": {
"jss-main": [
{
"uid": "a7e1a07a-ae81-4493-b32b-8e8d3a0d03c7",
"componentName": "Article",
"dataSource": "",
"params": {}
},
{
"uid": "22541242-9adf-4dc5-b3d7-2975e737371f",
"componentName": "CallToAction",
"dataSource": "{A396EEF0-25E9-4EF9-8EA6-A30AA0466EB1}",
"params": {},
"fields": {
"Description": {
"value": "Learn Next.js!"
},
"Button Text": {
"value": "Learn More!"
}
}
}
]
}
Create the component
- In VSCode, under
./rendering/src/components/Feature
- create a
CallToAction
folder - under that a
CallToAction.tsx
file
import {
Text,
RichText,
Field,
withDatasourceCheck
} from '@sitecore-jss/sitecore-jss-nextjs';
import { ComponentProps } from 'lib/component-props';
type CallToActionProps = ComponentProps & {
fields: {
Description: Field<string>;
"Button Text": Field<string>;
};
};
const CallToAction = ({ fields }: CallToActionProps): JSX.Element => (
<div className="callToAction">
<RichText tag="span" field={fields.Description} />
<button type="button">
<Text field={fields["Button Text"]} />
</button>
</div>
);
export default withDatasourceCheck()<CallToActionProps>(CallToAction);
Noteable differences with this component from a component pulling data from the context item:
- We pull data from
ComponentProps
instead ofsitecoreContext.route?.fields
withDatasourceCheck
- will only render if there is a datasource specified
Another thing to note is that if we have fields with spaces in the name, we must have quotes around the field name.
Explore
- We added the datasource to article page's Standard Values which will make the
Learn Next.js
data appear for all article page. Try changing the datasource for a specific article page toLearn Sitecore
. - Try removing the datasource. Notice the behavior of the component.
Knowledge check:
- How do we create content that is reusable in multiple places?
- How do we restrict a datasource's template to only be valid for a certain template?
- How do we specify a datasource's location?
- How do we render a component only if there is a datasource?
- Do we set renderings on datasource items? Where do we place renderings on instead?