diff --git a/CHANGELOG.md b/CHANGELOG.md index 8844917388..1d87b91091 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,6 +28,7 @@ Check the BYOC documentation for more info. ([#1568](https://github.com/Sitecore * `[sitecore-jss-react]` Built-in MissingComponent component can now accept "errorOverride" text in props - to be displayed in the yellow frame as a custom error message. ([#1568](https://github.com/Sitecore/jss/pull/1568)) * `[sitecore-jss-nextjs]` Support for public URL resolution in Netlify ([#1585](https://github.com/Sitecore/jss/pull/1585)) * `[templates/nextjs]` `[sitecore-jss-nextjs]` Better error handling for component-level data fetching ([#1586](https://github.com/Sitecore/jss/pull/1586)) +* `[sitecore-jss-react]` Fetch Data for FEaaS Components as part of Component SSR/SSG ([#1586](https://github.com/Sitecore/jss/pull/1590)) ### 🧹 Chores diff --git a/packages/sitecore-jss-react/src/components/FEaaSComponent.test.tsx b/packages/sitecore-jss-react/src/components/FEaaSComponent.test.tsx index 0029262f3d..a4517bb589 100644 --- a/packages/sitecore-jss-react/src/components/FEaaSComponent.test.tsx +++ b/packages/sitecore-jss-react/src/components/FEaaSComponent.test.tsx @@ -88,6 +88,7 @@ describe('', () => { ...requiredParams, ComponentDataOverride: '{ "foo": "bar", "baz": 1 }', }, + fetchedData: undefined, }; const wrapper = shallow(); expect(wrapper).to.have.length(1); @@ -166,5 +167,28 @@ describe('', () => { `data="${props.params?.ComponentDataOverride!.replace(/"/g, '"').replace(/\s/g, '')}"` ); }); + + it('should send prefetched data', () => { + const fetchedData = { + foo: 'bar', + baz: 42, + }; + + const props: FEaaSComponentProps = { + params: { + ...requiredParams, + ComponentDataOverride: '{ "foo": "test", "baz": 22 }', + }, + fetchedData, + }; + + const wrapper = shallow(); + + expect(wrapper).to.have.length(1); + const expectedData = JSON.stringify(fetchedData) + .replace(/"/g, '"') + .replace(/\s/g, ''); + expect(wrapper.html()).to.contain(`data="${expectedData}"`); + }); }); }); diff --git a/packages/sitecore-jss-react/src/components/FEaaSComponent.tsx b/packages/sitecore-jss-react/src/components/FEaaSComponent.tsx index bff84211fc..51b3cdb149 100644 --- a/packages/sitecore-jss-react/src/components/FEaaSComponent.tsx +++ b/packages/sitecore-jss-react/src/components/FEaaSComponent.tsx @@ -35,6 +35,10 @@ type FEaaSComponentServerProps = { * Default revision to be fetched. Should be 'staged' for editing/preview. Can be overriden by params.ComponentRevision */ revisionFallback?: RevisionType; + /** + * Fetched data from server component props for server rendering, based on rendering params. + */ + fetchedData?: FEAAS.DataScopes; }; /** @@ -73,16 +77,18 @@ export const FEaaSComponent = (props: FEaaSComponentProps): JSX.Element => { } let data: { [key: string]: unknown } = null; - if (props.params?.ComponentDataOverride) { - // Use override data if provided - try { - data = JSON.parse(props.params.ComponentDataOverride); - } catch (e) { - data = null; + if (props.fetchedData === null || props.fetchedData === undefined) { + if (props.params?.ComponentDataOverride) { + // Use override data if provided + try { + data = JSON.parse(props.params.ComponentDataOverride); + } catch (e) { + data = null; + } + } else if (props.fields) { + // Otherwise use datasource data (provided in fields) + data = getDataFromFields(props.fields); } - } else if (props.fields) { - // Otherwise use datasource data (provided in fields) - data = getDataFromFields(props.fields); } // FEaaS control would still be hydrated by client @@ -90,8 +96,8 @@ export const FEaaSComponent = (props: FEaaSComponentProps): JSX.Element => { // this also allows component to fall back to full client-side rendering when template or src is empty return ( { + try { + const { template } = await FEAAS.fetchComponent(src); + return template; + } catch (error) { console.error( `Fetch FEAAS component from ${src} failed. Ensure the component revision "${params.ComponentRevision || revisionFallback}" is present` ); - console.error(e); - // leave revision fallback in so we can re-try with client-side rendering - return { - revisionFallback, - }; + throw error; + } +} + +/** + * Fetches component data based on the provided data options. + * This function asynchronously fetches data using the FEAAS.DataSettings.fetch method. + * + * @param {FEAAS.DataOptions} dataOptions - Options to customize data fetching. + * @returns {Promise} A promise that resolves with the fetched data, + * or rejects with an error if data fetching encounters an issue. + * @throws {Error} If an error occurs during data fetching, it is propagated as an error. + */ +async function fetchData(dataOptions: FEAAS.DataOptions): Promise { + try { + const fetchedData = await FEAAS.DataSettings.fetch(dataOptions || {}); + return fetchedData; + } catch (error) { + console.error('Fetch FEAAS component data settings failed'); + throw error; } } diff --git a/yarn.lock b/yarn.lock index 5ec63419e3..7af98488bf 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5905,11 +5905,11 @@ __metadata: linkType: hard "@sitecore-feaas/clientside@npm:^0.3.0": - version: 0.3.0 - resolution: "@sitecore-feaas/clientside@npm:0.3.0" + version: 0.3.10 + resolution: "@sitecore-feaas/clientside@npm:0.3.10" peerDependencies: react-dom: ">=16.8.0" - checksum: cf1309e68b92f544ac7569cd444b211f153a8433bb7c42c8f74e5453cf58e164a95a1c59d4f78f06ae8980c5b4c25f09bf081880ab160b9dcb8b477a5c8b22d3 + checksum: b60391c33fa446b0fad164bc76babfc8cf2e7c892a741703df45d4acb74c6efd5aa2640650b85571d2d9d3072c02cf6653c3042cade6932365d214dc34402825 languageName: node linkType: hard