In the dynamic world of web development, the integration of Next.js with Sitecore XM Cloud is like opening a new chapter. It's not just about technology; it's about how we can make web development smarter and more intuitive.
In this blog, we're diving into the world of custom hooks in React, which are much more than just a technical feature—they're a game-changer in how we handle data and breathe life into our applications. These hooks aren't just about coding; they're about creating harmony between Next.js's smart server-side magic and Sitecore's robust content management, making our digital creations more efficient and user-friendly. Join us as we explore how custom hooks can transform your web applications, making them not just functional but remarkably efficient and effective in a Next.js and Sitecore XM Cloud ecosystem.
Custom Hook: useFetchItemFields
In our quest to enhance our Next.js applications with Sitecore XM Cloud, let's start with our first powerful custom hook: useFetchItemFields
. This hook simplifies fetching data from Sitecore using GraphQL, streamlining the process of displaying Sitecore-managed content in our Next.js front-end.
The useFetchItemFields
hook is designed to retrieve specific fields of a Sitecore item. This functionality is particularly useful for developers working with Sitecore as a CMS, enabling them to access and display customized content on their Next.js front-end.
Code breakdown:
export const useFetchItemFields = (sitecorePath: string) => {
const [itemFields, setItemFields] = useState(null);
const { sitecoreContext } = useSitecoreContext();
useEffect(() => {
const fetchData = async () => {
try {
const url =`${process.env.PUBLIC_URL}/api/graphQL/GetItemFields`;
<span class="hljs-keyword">const</span> response = <span class="hljs-keyword">await</span> fetch(url, {
<span class="hljs-attr">method</span>: <span class="hljs-string">'POST'</span>,
<span class="hljs-attr">headers</span>: {
<span class="hljs-string">'Content-Type'</span>: <span class="hljs-string">'application/json'</span>,
},
<span class="hljs-attr">body</span>: <span class="hljs-built_in">JSON</span>.stringify({
<span class="hljs-attr">sitecorePath</span>: sitecorePath,
<span class="hljs-attr">sitecoreLanguage</span>: sitecoreContext?.language ?? <span class="hljs-string">'en'</span>,
}),
});
<span class="hljs-keyword">if</span> (!response.ok) {
<span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">`HTTP error! Status: <span class="hljs-subst">${response.status}</span>`</span>);
}
<span class="hljs-keyword">const</span> result = <span class="hljs-keyword">await</span> response.json();
<span class="hljs-keyword">const</span> resultProps: itemProps = <span class="hljs-built_in">JSON</span>.parse(result);
setItemFields(resultProps);
} <span class="hljs-keyword">catch</span> (err) {
<span class="hljs-built_in">console</span>.error(<span class="hljs-string">'Error with PageScriptBox:'</span>, err);
}
};
fetchData();
}, [sitecorePath, sitecoreContext?.language]);
return itemFields;
};
How It Works
- The hook employs
useState
for managing the fetched data state (itemFields
) anduseEffect
for handling the data fetching operation. This setup ensures efficient state management and response to component lifecycle events. - Utilizing
useSitecoreContext
, the hook gains access to the current Sitecore context. This is particularly crucial for fetching language-specific content, ensuring users receive content in the correct language. - Within
useEffect
, afetchData
function is defined to conduct the API call. This function is the heart of the hook, where it communicates with the backend, requesting the appropriate content based on thesitecorePath
and the language setting from Sitecore’s context.
API Side for Data Fetching
The backend part of this setup involves an API handler that responds to the hook's requests:
export default async function handler(req, res) {
try {
const { sitecorePath, sitecoreLanguage } = req.body;
<span class="hljs-keyword">const</span> categoryDetailDb = <span class="hljs-keyword">await</span> GetItemFields(sitecorePath, sitecoreLanguage);
<span class="hljs-keyword">return</span> res.status(<span class="hljs-number">200</span>).json(<span class="hljs-built_in">JSON</span>.stringify(categoryDetailDb));
} catch (error) {
console.error('Error getting Side Nav Data:', error);
return res.status(500).json(JSON.stringify(error));
}
}
const GetItemFields = async (sitecorePath: string, sitecoreLanguage: string): Promise<any> => {
const graphQLClient = new GraphQLClient(config.graphQLEndpoint);
graphQLClient.setHeader('sc_apikey', config.sitecoreApiKey);
const pageComponentsQuery = gql query { item( path: "</span><span class="hljs-subst"><span class="hljs-string"><span class="hljs-subst">${sitecorePath}</span></span></span><span class="hljs-string">" language: "</span><span class="hljs-subst"><span class="hljs-string"><span class="hljs-subst">${sitecoreLanguage}</span></span></span><span class="hljs-string">" ) { id name fields{ id name value } } }
;
const data = await graphQLClient.request(pageComponentsQuery);
return data;
};
Integrating useFetchItemFields
in Next.js
Incorporating the useFetchItemFields
hook into your Next.js components is straightforward, enabling seamless Sitecore content retrieval:
Example Integration
const MyComponent = () => {
const itemFields = useFetchItemFields('{AAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA}');
// Render logic using the fetched itemFields
...
};
This custom hook, along with the API handler, forms a cohesive unit that simplifies fetching and displaying data from Sitecore in a Next.js application. It abstracts the complexities of GraphQL queries and state management, allowing developers to focus more on building the user interface.
Custom Hook: useTranslations
for Localization
Continuing our journey to enhance Next.js applications with Sitecore/XM Cloud, let's explore our second custom hook: useTranslations
. This hook is pivotal for maintaining an organized and efficient approach to handling translations and localization within your application.
Purpose of useTranslations
Centralized Translation Management
- The
useTranslations
hook leveragesuseI18n
from 'next-localization' to handle translations. - Its primary role is to provide a centralized place for managing all Sitecore dictionary items. This centralization is key for maintaining consistency and simplicity in the application's translation and localization process.
How It Works
import { useI18n } from 'next-localization';
export function useTranslations() {
const i18n = useI18n();
return {
creditLabel: i18n?.t('CreditLabel'),
creditsLabel: i18n?.t('CreditsLabel'),
submitSearchLabel: i18n?.t('SubmitSearchLabel'),
readMoreLabel: i18n?.t('ReadMoreLabel')
};
}
How It Works
- The hook starts by using
useI18n
to access the internationalization functionalities of the Next.js application. - It then defines a set of properties, each corresponding to a specific translation key (like 'CreditLabel', 'CreditsLabel', etc.). The hook fetches these translations from Sitecore's dictionary items, ensuring that the displayed content is appropriately localized.
- The hook returns an object containing all the required labels and texts. This object can be used throughout your Next.js components for displaying translated content.
Integrating useTranslations
in Next.js
First, call useTranslations
at the beginning of your component to access the translations object.
const translations = useTranslations();
Then Use the properties of the translations
object to display localized text in your component. For instance, if you want to display a breadcrumb home label, you would use translations.readMoreLabel
.
<Text>
{translations.readMoreLabel}
</Text>
Benefits of useTranslations
- Maintainability: By centralizing the management of all Sitecore dictionary items,
useTranslations
significantly enhances the maintainability of your codebase. - Scalability: It allows for easy scalability by adding new languages or modifying existing translations.
- Consistency: Ensures consistency in implementing and displaying translations across different components.
This hook is a testament to the power of custom hooks in enhancing not just the functionality but also the organization and maintainability of Next.js applications, especially in multilingual settings.
Closing Thoughts on Next.js Hooks in XM Cloud
In today’s exploration, we’ve unlocked the magic of useFetchItemFields
and useTranslations
hooks, transforming our Next.js applications in the Sitecore XM Cloud environment. These aren’t just mere tools; they're the essence that makes our apps vibrant, intelligent, and in tune with diverse user needs. It's like giving voice and understanding to our digital creations, all through the simplicity and brilliance of these hooks. And what's exciting is that this is just the start. Keep an eye out for our future posts, where we'll introduce more innovative hooks, each adding a new dimension to our web development adventures. Stay tuned for more!
References
For further information and a deeper understanding of the concepts discussed in this blog, the following resources have been referenced:
- React Dev - Reusing Logic with Custom Hooks: An official guide by React explaining the concept and implementation of custom hooks.
- Sitecore Helix - Language Support and Dictionary: Detailed documentation on Sitecore's approach to multilingual content management.
- Sitecore Documentation - Using GraphQL to Fetch Component-Level Data in JSS Next.js Apps: A guide on leveraging GraphQL in Sitecore for JSS Next.js applications.