Setting up 404 and 500 pages is always part of the overall configuration of a website. You need to have those pages to gracefully and correctly tell the end-user to stop looking for web pages that don’t exist on your site. It proved to be a bit of work in a Sitecore JSS context running with Static Site Generation (SSG) and the multisite plugin.
The issue stems from the getStaticProps call to fetch the site information:
export const getStaticProps: GetStaticProps = async (context) => {
const site = siteResolver.getByName(config.sitecoreSiteName);
...
}
Notice that the siteResolver is fetching the site defined in the confing.sitecoreSiteName. In a multisite setup, however, this will result in incorrectly serving the main site’s 404/500 pages for all of the sites. The correct config attribute to use should be config.sites where the array of site definitions is set during build.
// use the value of config.sites which contains the site definitions of all the sites in the current tenant
const sites = JSON.parse(config.sites) as SiteInfo[];
The next step is to actually fetch the 404/500 page configured on the SXA Site Setting item using the GraphQLErrorPagesService:

if (sites && sites.length) {
// we need to use regular for-loop here because array iteration methods like map are not aync aware
for (const site of sites) {
const errorPagesService = new GraphQLErrorPagesService({
clientFactory: graphQLClientFactory,
siteName: site.name,
language,
retries:
(process.env.GRAPH_QL_SERVICE_RETRIES &&
parseInt(process.env.GRAPH_QL_SERVICE_RETRIES, 10)) ||
0,
});
try {
// fetch each site's error page settings using the ootb errorPagesService
const resultErrorPages = await errorPagesService.fetchErrorPages();
...
} catch (error) {
...
}
}
}
If your page layout makes a GraphQL call to fetch components, you will need to implement an extra step. For example, on our site, the Header and Footer components execute a GraphQL query to fetch all the data needed to render themselves. On a regular page, the component-props.ts plugin runs for component-level data fetching. Because the 404/500 pages are statically generated and does not go through the typical JSS page routing process, you will need to explicitly call the ComponentPropsService to get the complete layout data:
const componentPropsService = new ComponentPropsService();
// we need to use regular for-loop here because array iteration methods like map are not aync aware
for (const site of siteErrorPagePaths) {
const ctx = context;
// force context param to use site-specific error page path
ctx.params = {
path: [`_site_${site.siteName}`, site.errorPagePath],
};
try {
if (site.layoutData) {
const componentProps = await componentPropsService.fetchStaticComponentProps({
layoutData: site.layoutData,
context,
moduleFactory,
});
if (componentProps) {
...
}
}
} catch (error) {
...
}
}
Here’s the gist of how everything works together: https://gist.github.com/m-are/708a963a7098bd2271ba9c4595007d1f
Leave a comment