2

In a Headless Sitecore site I'm doing the front-end on, I'm trying to implement search. It's a JSS/Next.js based front end on top of the Sitecore back end. We've got:

  • JSS 20, Next 12.2, Sitecore 10.2
  • Optimized for SSG/ISR
  • A GraphQL API to get results to display.
  • A SearchResults component which is responsible for rendering results.

I'm trying to implement the component level data fetching approach outlined in the sitecore docs, but I guess I'm missing something. The getServerSideProps function exported from the component simply isn't called. Here's the relevant structure of my SearchResults component:

import {
  constants,
  GetServerSideComponentProps,
  useComponentProps
} from '@sitecore-jss/sitecore-jss-nextjs';
import { GraphQLClient } from '@lib/graphql-client';
import config from '@temp/config';

const SearchResults = ({ fields, rendering }) => {
  const externalData = useComponentProps(rendering?.uid); 

  console.log("Search Result external data")
  console.dir(externalData); <-- this is always `undefined`

  return (
    <section>
      [...redacted for clarity]
    </section>
  );
}

export const getServerSideProps = (rendering, layoutData) => {

  console.log("SERVER SIDE PROPS!") // <-- This never gets called

  if (process.env.JSS_MODE === constants.JSS_MODE.DISCONNECTED) {
    return null;
  }

  const client = GraphQLClient(
    `${config.sitecoreApiHost}/api/Search?sc_apikey=${config.sitecoreApiKey}`
  );


  return client;
}

export { SearchResults };

The doc linked above makes mention of the ComponentPropsService finding the component to call the getServerSideProps function:

The ComponentPropsService traverses the layout service data and looks at all the renderings. To find the components that require data fetching, the service spies on the component using the rendering.componentName against the list of component registrations in the src/temp/componentFactory file.

The SearchResults component is definitely defined in the src/temp/componentFactory file, but I must be missing something. That function, getServerSideProps, simply never gets called. If I'm supposed to somehow register the component with the ComponentPropsService so it knows about it and can call that function, it's not clear to me how to do that. Am I even on the right track?

1 Answer 1

2

The problem is mixing and matching SSR and SSG between components and pages. If your page is SSG, you must set your components to SSG also, to use SSR on your component, your page must be SSR.

Full disclosure, we worked together on Sitecore Slack to get the answer:

A better way to do this would be to use an api call to a function on the component, no instead of relying on the Next.js framework to call the getServerSideProps, the function is called when the main component is generated. Here is an update of your code as an example:

import {
  constants,
  GetServerSideComponentProps,
  useComponentProps
} from '@sitecore-jss/sitecore-jss-nextjs';
import { GraphQLClient } from '@lib/graphql-client';
import config from '@temp/config';
​
const SearchResults = ({ fields, rendering }) => {
  const externalData = getSearchData(); 
​
  console.log("Search Result external data")
  console.dir(externalData); <-- this should now contain data
  
  // use externalData in your return
​
  return (
    <section>
      [...redacted for clarity]
    </section>
  );
}
​
const getSearchData = () =>  {
  if (process.env.JSS_MODE === constants.JSS_MODE.DISCONNECTED) {
    return null;
  }
​
  const client = GraphQLClient(
    `${config.sitecoreApiHost}/api/Search?sc_apikey=${config.sitecoreApiKey}`
  );
​
  return client;
}
​
export { SearchResults };

Notice that I have replaced the getServerSideProps function with getSearchData, and this function is called directly from your SearchResults component.

This will generate the results.

To take this further and have results created on the client side, you can also create a button that makes the call and dynamically updates the props on the component via ajax, this would be a way to add faceting or filtering to the main set of search results too.

2
  • Thanks @RichardSeal, your suggestion to abandon the getServerSideProps approach was definitely the way to move forward. It's unfortunate that the Sitecore docs don't make any mention of the rendering method distinction when they talk about using that for component level data fetching. They suggest "just do this and it will work" without context. Even the Sitecore support person we were in contact with basically said "just do this and it will work". Very frustrating. Thanks again for your guidance. Jul 29 at 11:04
  • I'm failing to understand the purpose of getting external data through the hook useComponentProps then. Most front-end developers use Storybook, and even if you pass in props from storybook arg (data) that came from a Sitecore LayoutData json response, the hook fails and breaks the component. 1 hour ago

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.