From e1ac5304e51669ae5ea0f94ed37078606bd62c95 Mon Sep 17 00:00:00 2001 From: pamo_sitecore Date: Mon, 6 Jul 2026 11:43:57 +0530 Subject: [PATCH] Make component fields optional in props across multiple components for improved flexibility and error handling --- .../src/components/sxa/ContentBlock.tsx | 4 +- .../src/components/sxa/Image.tsx | 16 ++----- .../src/components/sxa/LinkList.tsx | 8 ++-- .../src/components/sxa/Navigation.tsx | 46 +++++++++++-------- .../components/sxa/NavigationList.client.tsx | 10 ++-- .../src/components/sxa/Promo.tsx | 4 +- .../src/components/sxa/RichText.tsx | 2 +- .../src/components/sxa/content-block.props.ts | 6 +-- .../src/components/sxa/link-list.props.ts | 14 +++--- .../src/components/sxa/navigation.props.ts | 2 +- .../src/components/sxa/page-content.props.ts | 8 ++-- .../src/components/sxa/promo.props.ts | 12 ++--- .../src/components/sxa/rich-text.props.ts | 4 +- .../src/components/sxa/sxa-image.props.ts | 2 +- .../src/components/sxa/title.props.ts | 20 ++++---- 15 files changed, 82 insertions(+), 76 deletions(-) diff --git a/examples/kit-nextjs-location-finder/src/components/sxa/ContentBlock.tsx b/examples/kit-nextjs-location-finder/src/components/sxa/ContentBlock.tsx index 17449b209..67ef485ee 100644 --- a/examples/kit-nextjs-location-finder/src/components/sxa/ContentBlock.tsx +++ b/examples/kit-nextjs-location-finder/src/components/sxa/ContentBlock.tsx @@ -11,9 +11,9 @@ import { JSX } from 'react'; */ const ContentBlock = ({ fields }: ContentBlockProps): JSX.Element => (
- + - +
); diff --git a/examples/kit-nextjs-location-finder/src/components/sxa/Image.tsx b/examples/kit-nextjs-location-finder/src/components/sxa/Image.tsx index f6cc76798..958125641 100644 --- a/examples/kit-nextjs-location-finder/src/components/sxa/Image.tsx +++ b/examples/kit-nextjs-location-finder/src/components/sxa/Image.tsx @@ -1,23 +1,13 @@ import { - Field, - ImageField, NextImage as ContentSdkImage, Link as ContentSdkLink, - LinkField, Text, } from '@sitecore-content-sdk/nextjs'; import React from 'react'; import { ComponentProps } from '@/lib/component-props'; +import type { SxaImageProps } from './sxa-image.props'; -interface ImageFields { - Image: ImageField; - ImageCaption: Field; - TargetUrl: LinkField; -} - -interface ImageProps extends ComponentProps { - fields: ImageFields; -} +type ImageProps = ComponentProps & SxaImageProps; const ImageWrapper: React.FC<{ className: string; @@ -92,7 +82,7 @@ export const Default: React.FC = (props) => { className={`component image ${styles ?? ''}`} id={typeof id === 'string' ? id : undefined} > - {shouldWrapWithLink ? ( + {shouldWrapWithLink && fields.TargetUrl ? ( diff --git a/examples/kit-nextjs-location-finder/src/components/sxa/LinkList.tsx b/examples/kit-nextjs-location-finder/src/components/sxa/LinkList.tsx index eaf076c51..9377ca8e5 100644 --- a/examples/kit-nextjs-location-finder/src/components/sxa/LinkList.tsx +++ b/examples/kit-nextjs-location-finder/src/components/sxa/LinkList.tsx @@ -37,13 +37,14 @@ export const Default = (props: LinkListProps): JSX.Element => { const id = props.params.RenderingIdentifier; if (datasource) { - const list = datasource.children.results + const results = datasource.children?.results ?? []; + const list = results .filter((element: LinkListResultFieldLink) => element?.field?.link) .map((element: LinkListResultFieldLink, key: number) => ( )); @@ -115,7 +116,8 @@ export const AnchorNav = (props: LinkListProps): JSX.Element => { }, []); if (datasource) { - const list = datasource.children.results + const results = datasource.children?.results ?? []; + const list = results .filter((element: LinkListResultFieldLink) => element?.field?.link) .map((element: LinkListResultFieldLink, key: number) => { const link = element.field.link; diff --git a/examples/kit-nextjs-location-finder/src/components/sxa/Navigation.tsx b/examples/kit-nextjs-location-finder/src/components/sxa/Navigation.tsx index 896fdc898..0ed9929f5 100644 --- a/examples/kit-nextjs-location-finder/src/components/sxa/Navigation.tsx +++ b/examples/kit-nextjs-location-finder/src/components/sxa/Navigation.tsx @@ -12,36 +12,46 @@ import type { NavigationFields, NavigationProps } from './navigation.props'; export type { NavigationFields, NavigationProps }; -const getNavigationText = function (props: { fields: NavigationFields }): JSX.Element | string { +const getNavigationText = function (props: { fields?: NavigationFields }): JSX.Element | string { + const navigationFields = props.fields; + if (!navigationFields) { + return ''; + } + let text; - if (props.fields.NavigationTitle) { - text = ; - } else if (props.fields.Title) { - text = ; + if (navigationFields.NavigationTitle) { + text = ; + } else if (navigationFields.Title) { + text = ; } else { - text = props.fields.DisplayName; + text = navigationFields.DisplayName; } return text; }; -const getLinkField = (props: { fields: NavigationFields }): LinkField => ({ +const getLinkField = (props: { fields?: NavigationFields }): LinkField => ({ value: { - href: props.fields.Href, + href: props.fields?.Href ?? '', title: getLinkTitle(props), - querystring: props.fields.Querystring, + querystring: props.fields?.Querystring ?? '', }, }); -const getLinkTitle = (props: { fields: NavigationFields }): string | undefined => { +const getLinkTitle = (props: { fields?: NavigationFields }): string | undefined => { + const navigationFields = props.fields; + if (!navigationFields) { + return undefined; + } + let title; - if (props.fields.NavigationTitle?.value) { - title = props.fields.NavigationTitle.value.toString(); - } else if (props.fields.Title?.value) { - title = props.fields.Title.value.toString(); + if (navigationFields.NavigationTitle?.value) { + title = navigationFields.NavigationTitle.value.toString(); + } else if (navigationFields.Title?.value) { + title = navigationFields.Title.value.toString(); } else { - title = props.fields.DisplayName; + title = navigationFields.DisplayName; } return title; @@ -59,7 +69,7 @@ export const Default = (props: NavigationProps): JSX.Element => { : ''; const id = props.params != null ? props.params.RenderingIdentifier : null; - if (!Object.values(props.fields).length) { + if (!props.fields || !Object.values(props.fields).length) { return (
[Navigation]
@@ -72,7 +82,7 @@ export const Default = (props: NavigationProps): JSX.Element => { props.handleClick(event); }; - const list = Object.values(props.fields) + const list = Object.values(props.fields ?? {}) .filter((element) => element) .map((element: NavigationFields, key: number) => ( { }; export const ButtonNavigation = (props: NavigationProps): JSX.Element => { - const list = Object.values(props.fields).filter((element) => element); + const list = Object.values(props.fields ?? {}).filter((element) => element); return (
diff --git a/examples/kit-nextjs-location-finder/src/components/sxa/NavigationList.client.tsx b/examples/kit-nextjs-location-finder/src/components/sxa/NavigationList.client.tsx index 079572f0b..2021ec030 100644 --- a/examples/kit-nextjs-location-finder/src/components/sxa/NavigationList.client.tsx +++ b/examples/kit-nextjs-location-finder/src/components/sxa/NavigationList.client.tsx @@ -8,12 +8,12 @@ import type { JSX } from 'react'; import type { NavigationFields } from './navigation.props'; type NavigationListProps = { - fields: NavigationFields; + fields?: NavigationFields; handleClick: (event?: React.MouseEvent) => void; relativeLevel: number; isEditing: boolean; - getLinkField: (props: { fields: NavigationFields }) => LinkField; - getNavigationText: (props: { fields: NavigationFields }) => JSX.Element | string; + getLinkField: (props: { fields?: NavigationFields }) => LinkField; + getNavigationText: (props: { fields?: NavigationFields }) => JSX.Element | string; }; /** @@ -27,6 +27,10 @@ export const NavigationList = ({ getLinkField, getNavigationText, }: NavigationListProps) => { + if (!fields) { + return null; + } + const [active, setActive] = useState(false); const classNameList = `${fields.Styles.concat('rel-level' + relativeLevel).join(' ')}`; diff --git a/examples/kit-nextjs-location-finder/src/components/sxa/Promo.tsx b/examples/kit-nextjs-location-finder/src/components/sxa/Promo.tsx index ff1783409..8f3f615f9 100644 --- a/examples/kit-nextjs-location-finder/src/components/sxa/Promo.tsx +++ b/examples/kit-nextjs-location-finder/src/components/sxa/Promo.tsx @@ -63,7 +63,7 @@ export const Default = (props: PromoProps): JSX.Element => { className="font-bold py-1 px-3 mx-6 mb-4 mt-auto relative b-0" asChild > - + {props.fields.PromoLink ? : null}
@@ -112,7 +112,7 @@ export const CenteredCard = (props: PromoProps): JSX.Element => { className="font-bold text-xl text-center w-full py-1 px-3 ml-4 mb-4 relative b-0" asChild > - + {props.fields.PromoLink ? : null} diff --git a/examples/kit-nextjs-location-finder/src/components/sxa/RichText.tsx b/examples/kit-nextjs-location-finder/src/components/sxa/RichText.tsx index 8caaa4c68..699e8d0e0 100644 --- a/examples/kit-nextjs-location-finder/src/components/sxa/RichText.tsx +++ b/examples/kit-nextjs-location-finder/src/components/sxa/RichText.tsx @@ -10,7 +10,7 @@ export const Default = ({ params, fields }: RichTextProps): JSX.Element => {
{fields ? (
- +
) : ( Rich text diff --git a/examples/kit-nextjs-location-finder/src/components/sxa/content-block.props.ts b/examples/kit-nextjs-location-finder/src/components/sxa/content-block.props.ts index 957c85009..068ef08c0 100644 --- a/examples/kit-nextjs-location-finder/src/components/sxa/content-block.props.ts +++ b/examples/kit-nextjs-location-finder/src/components/sxa/content-block.props.ts @@ -2,11 +2,11 @@ import type { Field } from '@sitecore-content-sdk/nextjs'; import type { OptionalComponentProps } from '@/lib/component-props'; export type ContentBlockFields = { - heading: Field; - content: Field; + heading?: Field; + content?: Field; }; export type ContentBlockProps = OptionalComponentProps & { - fields: ContentBlockFields; + fields?: ContentBlockFields; }; diff --git a/examples/kit-nextjs-location-finder/src/components/sxa/link-list.props.ts b/examples/kit-nextjs-location-finder/src/components/sxa/link-list.props.ts index ea6a3c950..f990f72b7 100644 --- a/examples/kit-nextjs-location-finder/src/components/sxa/link-list.props.ts +++ b/examples/kit-nextjs-location-finder/src/components/sxa/link-list.props.ts @@ -8,20 +8,20 @@ export type LinkListResultFieldLink = { }; export type LinkListFields = { - data: { - datasource: { - children: { - results: LinkListResultFieldLink[]; + data?: { + datasource?: { + children?: { + results?: LinkListResultFieldLink[]; }; - field: { - title: TextField; + field?: { + title?: TextField; }; }; }; }; export type LinkListProps = OptionalComponentProps & { - fields: LinkListFields; + fields?: LinkListFields; }; export type LinkListItemProps = { diff --git a/examples/kit-nextjs-location-finder/src/components/sxa/navigation.props.ts b/examples/kit-nextjs-location-finder/src/components/sxa/navigation.props.ts index 7042f6a88..3641f13be 100644 --- a/examples/kit-nextjs-location-finder/src/components/sxa/navigation.props.ts +++ b/examples/kit-nextjs-location-finder/src/components/sxa/navigation.props.ts @@ -13,7 +13,7 @@ export type NavigationFields = { }; export type NavigationProps = OptionalComponentProps & { - fields: Record; + fields?: Record; handleClick: (event?: React.MouseEvent) => void; relativeLevel: number; isEditing?: boolean; diff --git a/examples/kit-nextjs-location-finder/src/components/sxa/page-content.props.ts b/examples/kit-nextjs-location-finder/src/components/sxa/page-content.props.ts index bcfef90b5..96b602bfd 100644 --- a/examples/kit-nextjs-location-finder/src/components/sxa/page-content.props.ts +++ b/examples/kit-nextjs-location-finder/src/components/sxa/page-content.props.ts @@ -2,13 +2,13 @@ import type { LinkField, RichTextField, TextField } from '@sitecore-content-sdk/ import type { OptionalComponentProps } from '@/lib/component-props'; export type PageContentFields = { - Title: TextField; - Content: RichTextField; - MainLink: LinkField; + Title?: TextField; + Content?: RichTextField; + MainLink?: LinkField; }; export type PageContentProps = OptionalComponentProps & { - fields: PageContentFields; + fields?: PageContentFields; }; export type PageContentComponentContentProps = { diff --git a/examples/kit-nextjs-location-finder/src/components/sxa/promo.props.ts b/examples/kit-nextjs-location-finder/src/components/sxa/promo.props.ts index 5ff94557f..6ad2e1684 100644 --- a/examples/kit-nextjs-location-finder/src/components/sxa/promo.props.ts +++ b/examples/kit-nextjs-location-finder/src/components/sxa/promo.props.ts @@ -2,14 +2,14 @@ import type { Field, ImageField, LinkField } from '@sitecore-content-sdk/nextjs' import type { OptionalComponentProps } from '@/lib/component-props'; export type PromoFields = { - PromoIcon: ImageField; - PromoText: Field; - PromoLink: LinkField; - PromoText2: Field; - PromoText3: Field; + PromoIcon?: ImageField; + PromoText?: Field; + PromoLink?: LinkField; + PromoText2?: Field; + PromoText3?: Field; }; export type PromoProps = OptionalComponentProps & { - fields: PromoFields; + fields?: PromoFields; }; diff --git a/examples/kit-nextjs-location-finder/src/components/sxa/rich-text.props.ts b/examples/kit-nextjs-location-finder/src/components/sxa/rich-text.props.ts index e7d940bd4..30496875a 100644 --- a/examples/kit-nextjs-location-finder/src/components/sxa/rich-text.props.ts +++ b/examples/kit-nextjs-location-finder/src/components/sxa/rich-text.props.ts @@ -2,10 +2,10 @@ import type { Field } from '@sitecore-content-sdk/nextjs'; import type { OptionalComponentProps } from '@/lib/component-props'; export type RichTextFields = { - Text: Field; + Text?: Field; }; export type RichTextProps = OptionalComponentProps & { - fields: RichTextFields; + fields?: RichTextFields; }; diff --git a/examples/kit-nextjs-location-finder/src/components/sxa/sxa-image.props.ts b/examples/kit-nextjs-location-finder/src/components/sxa/sxa-image.props.ts index b634d4b31..c49cbd9a6 100644 --- a/examples/kit-nextjs-location-finder/src/components/sxa/sxa-image.props.ts +++ b/examples/kit-nextjs-location-finder/src/components/sxa/sxa-image.props.ts @@ -8,6 +8,6 @@ export type SxaImageFields = { }; export type SxaImageProps = OptionalComponentProps & { - fields: SxaImageFields; + fields?: SxaImageFields; }; diff --git a/examples/kit-nextjs-location-finder/src/components/sxa/title.props.ts b/examples/kit-nextjs-location-finder/src/components/sxa/title.props.ts index e87e7a3e7..240bc9239 100644 --- a/examples/kit-nextjs-location-finder/src/components/sxa/title.props.ts +++ b/examples/kit-nextjs-location-finder/src/components/sxa/title.props.ts @@ -1,26 +1,26 @@ import type { OptionalComponentProps } from '@/lib/component-props'; export type TitleFields = { - data: { - datasource: { - url: { + data?: { + datasource?: { + url?: { path: string; siteName: string; }; - field: { - jsonValue: { + field?: { + jsonValue?: { value: string; metadata?: { [key: string]: unknown }; }; }; }; - contextItem: { - url: { + contextItem?: { + url?: { path: string; siteName: string; }; - field: { - jsonValue: { + field?: { + jsonValue?: { value: string; metadata?: { [key: string]: unknown }; }; @@ -30,7 +30,7 @@ export type TitleFields = { }; export type TitleProps = OptionalComponentProps & { - fields: TitleFields; + fields?: TitleFields; }; export type TitleComponentContentProps = {