get droplink rendering parameter value in xm cloud

You have to set the following configuration to true to get the detailed information on rendering parameters set.

<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
  <sitecore>
    <settings>
      <setting name="LayoutService.DetailedRenderingParams" value="false">
        <patch:attribute name="value">true</patch:attribute>
    </setting>
   </settings>
 </sitecore>
</configuration>
By default this setting comes as false.


XM Cloud - Getting component specific data

If you are binding your component with the layout response but feel that if a custom property can come in the layout response and you could bind that in your component.

But as you know you can not insert the custom property in the layout response without heavy customisation but we have a way to do so.

We can achieve this on component level using  useComponentProps and  getStaticProps: GetStaticComponentProps methods in XM cloud.

Lets understand this quickly.

You have a component like follows:

import type {
  ComponentRendering,
  Field,
  GetStaticComponentProps,
  ImageField,
  LayoutServiceData,
  LinkField,
} from '@sitecore-jss/sitecore-jss-nextjs';
import { useComponentProps } from '@sitecore-jss/sitecore-jss-nextjs';
type BlogIndexVariationOneProps = ComponentProps & {
  fields?: BlogIndexVariationOneFields;
};

function BlogIndexVariationOne({
  fields = {},
  rendering = {} as ComponentRendering,
}: BlogIndexVariationOneProps) {

const path = useComponentProps<string>(rendering?.uid);

return (
// your html here
)

}

In the component BlogIndexVariationOne we are passing the BlogIndexVariationOneProps. In this fields will be mapped from the layout response but rendering is worth to pay attention here that we will discuss the usage of it further in this blog.

Now assume that under this component you are returning the HTML with the data received in the fields object and additionaly you have a requirement to show the current page URL in any of the <div> tag also.

So as you know the current url will not work from  window.location.href or writing the same in the useEffect() or even useLocation() won't work until you don't wrap your component in the <Router> tag.

So how can we get the current url then? Here we will use the getStaticProps: GetStaticComponentProps method as shown below:

export const getStaticProps: GetStaticComponentProps = async (

  _rendering: ComponentRendering,
  layoutData: LayoutServiceData,
  context
) => {
  return context?.params?.requestPath
}

Here we are returning the requestPath provided by sitecore's context and it is returning the string type. 

Now how will we use this in our component? Here comes the role of rendering that we passed in the component in the line const path = useComponentProps<string>(rendering?.uid);. So rendering?.uid in the useComponentProps tells the component that something is being passed from getStaticProps: GetStaticComponentProps as string return type so use that.

And voilla, now you can use the request path in your code.

So in place of context?.params?.requestPath you can use your any API fetch if you want it to be fetched using this although the best practice for getting the API data is to use in the useEffect() but this is also one more way to use.

Thanks!

To extend it further with one more example.

In Sitecore JSS / XM Cloud projects (especially with Next.js),
each component can export a getStaticProps method that defines how to fetch its data during build time or static regeneration.

The framework (Sitecore + Next.js) runs this function:

  • once at build time for static generation (next build), or

  • on demand when the page is rebuilt (ISR).

The result of this function gets attached to the component rendering JSON as componentProps — which is what useComponentProps(uid) later reads.


Suppose you have method as follows that get the data using graphql query:

export const getStaticProps: GetStaticComponentProps = async ( _rendering: ComponentRendering, layoutData: LayoutServiceData, context ) => { // Create a GraphQL client to talk to Sitecore XM Cloud const graphQLClient = new GraphQLRequestClient(config.graphQLEndpoint, { apiKey: config.sitecoreApiKey, }); // Get the current page path (used to construct URLs) const basePath = (layoutData?.sitecore?.context?.itemPath ?? '').replace(/\/,-w-,/, ''); /* page query param handling */ const page = (() => { const path = context?.params?.requestPath; if (path === undefined) return ''; if (!Array.isArray(path)) return ''; const pageNumber = parseInt(path[path.length - 1]); if (isNaN(pageNumber)) return ''; return pageNumber.toString(); })(); /* fetch blog articles */ let updatedResult = []; let query = CHILD_BLOGS_GQL; // Replace placeholders in the GraphQL query with actual IDs query = query.replaceAll('__ROOT_ID__', Constants?.Ids?.BlogItemParent); query = query.replaceAll('__TEMPLATE_ID__', Constants?.TemplateIds?.BlogDetailPage); // Execute the GraphQL query and return all articles updatedResult = await getAllItems<BlogTemplat>(graphQLClient, query); // Return the data that will be serialized into componentProps return { page: page, result: updatedResult, basePath: basePath }; };

and the top somewhere when you would have started your component, there will be code like

const query = useComponentProps<queryResult>(rendering?.uid);
  const data = query?.result;

and,

then do you logic operation based on data variable.

Sitecore powershell script to update rendering parameters and datasource item fields data

 We had one requirement to change the component's display on almost 1400 pages and doing so we had to follow following things:

1. Update the rendering parameters on the item

$parameters = [ordered]@{"DisplayContentInCard" = "1"; "ApplyBackground" = "1"; "AlignImageRight" = "1" }

$rendering | Set-RenderingParameter -Parameter $parameters | Set-Rendering -Item $pageItem -FinalLayout

 2. Update the datasource item's field data.

if ($datasource.StartsWith("local:")) {
                    $datasource = $datasource.Replace("local:", $pageItem.Paths.Path)
                }
                if ($datasource.StartsWith("/sitecore")) {
                    $datasourceItemNewVersion = Add-ItemVersion -Path "master:$($datasource)"
                    $datasourceItem = Get-Item -Path "master:$($datasourceItemNewVersion.FullPath)"
                    $quoteInitiation = "{0xxxxx0-FA49-445A-95FC-E3xxxxx1E3}"
                    if ($null -ne $dataSourceItem) {
                        $dataSourceItem.Editing.BeginEdit()
                        $dataSourceItem["quote"] = $quoteInitiation
                        $dataSourceItem["Link"] = ""
                        $dataSourceItem.Editing.EndEdit()
                        #$item = Get-Item -Path "master:$($dataSourceItem.FullPath)"
                        Publish-Item -Path "master:$($dataSourceItem.FullPath)" -PublishMode Smart -Target Edge
                        # Datasource item fields update - End
                    }
                    else {
                        Write-Host "Unable to process $($dataSourceItem.FullPath)"
                    }
                }
                else {
                    # this will execute when datasource is in GUID format
                    $datasourceItemNewVersion = Add-ItemVersion -Path "master:$($datasource)"
                    $datasourceItem = Get-Item "$($datasource)"
                    $quoteInitiation = "{03sss7FD0-FA49-445A-95FC-E35xxxxE3}"
                    if ($null -ne $dataSourceItem) {
                        $dataSourceItem.Editing.BeginEdit()
                        $dataSourceItem["quote"] = $quoteInitiation
                        $dataSourceItem["Link"] = ""
                        $dataSourceItem.Editing.EndEdit()
                        #$item = Get-Item -Path "master:$($dataSourceItem.FullPath)"
                        Publish-Item -Path "master:$($dataSourceItem.FullPath)" -PublishMode Smart -Target Edge
                        # Datasource item fields update - End
                    }
                    else {
                        Write-Host "Unable to process $($dataSourceItem.FullPath)"
                    }
                }

3. Update the main page with one droplink field to be set with the specific item.

$defaultProductOptionItemId = "{E2xxxxx-5DD0-4188-ABED-5Axxxxx56}";
                if ([string]::IsNullOrEmpty($pageItem["productionOption"])) {
                    $pageItem.Editing.BeginEdit()
                    $pageItem["productionOption"] = $defaultProductOptionItemId
                    $pageItem.Editing.EndEdit()
                    Publish-Item -Path "master:$($pageItem.FullPath)" -PublishMode Smart -Target Edge
                }

4. Export the info in the excel

    $props = @{
        InfoTitle       = "Quote Initiation."
        InfoDescription = "Processing for quote initiation of City pages for Auto owners."
        PageSize        = 25
    }

    $items |
    Show-ListView @props -Property @{Label = "Name"; Expression = { $_.DisplayName } },
    @{Label = "Id"; Expression = { $_.Id } },
    @{Label = "Template Name"; Expression = { $_.TemplateName } },
    @{Label = "Path"; Expression = { $_.ItemPath } }

Now the complete script is as follows:

# Product City Page - Auto

function ProcessProductLocationPage_Auto {
    $allItems = Get-ChildItem -Path "master://sitecore/content/SiteRoot/Home/States" -Recurse
    ForEach ($item in $allItems) {
        if ($item.TemplateName -match "City" -AND $item.Name -match "auto") {
            $newItemVersion = Add-ItemVersion -Path "master:$($item.FullPath)"
            $pageItem= Get-Item -Path "master:$($newItemVersion.FullPath)"
            try {
                # Update rendering parameters - Start
                $fityFiftyRenderingId = "{3FXXXE058-F909-4813-B4AA-92XXXXX5DE}"
                $defaultLayout = Get-LayoutDevice "Default"
                $renderings = Get-Rendering -Item $pageItem-Device $defaultLayout -FinalLayout
                $datasource = ""
                foreach ($rendering in $renderings) {
                    if ($rendering.ItemId -eq $fityFiftyRenderingId) {
                        $parameters = [ordered]@{"DisplayContentInCard" = "1"; "ApplyBackground" = "1"; "AlignImageRight" = "1" }
                        $rendering | Set-RenderingParameter -Parameter $parameters | Set-Rendering -Item $pageItem-FinalLayout
                        $datasource = $rendering.Datasource                
                    }
                }
                # Datasource item fields update - Start    
                # Check if the data source path has a special prefix
                if ($datasource.StartsWith("local:")) {
                    $datasource = $datasource.Replace("local:", $pageItem.Paths.Path)
                }
                if ($datasource.StartsWith("/sitecore")) {
                    $datasourceItemNewVersion = Add-ItemVersion -Path "master:$($datasource)"
                    $datasourceItem = Get-Item -Path "master:$($datasourceItemNewVersion.FullPath)"
                    $quoteInitiation = "{0ddddD0-FA49-445A-95FC-E35dddddE3}"
                    if ($null -ne $dataSourceItem) {
                        $dataSourceItem.Editing.BeginEdit()
                        $dataSourceItem["quote"] = $quoteInitiation
                        $dataSourceItem["Link"] = ""
                        $dataSourceItem.Editing.EndEdit()
                        #$item = Get-Item -Path "master:$($dataSourceItem.FullPath)"
                        Publish-Item -Path "master:$($dataSourceItem.FullPath)" -PublishMode Smart -Target Edge
                        # Datasource item fields update - End
                    }
                    else {
                        Write-Host "Unable to process $($dataSourceItem.FullPath)"
                    }
                }
                else {
                    # this will execute when datasource is in GUID format
                    $datasourceItemNewVersion = Add-ItemVersion -Path "master:$($datasource)"
                    $datasourceItem = Get-Item "$($datasource)"
                    $quoteInitiation = "{0dddddD0-FA49-445A-95FC-E3xxxxx31E3}"
                    if ($null -ne $dataSourceItem) {
                        $dataSourceItem.Editing.BeginEdit()
                        $dataSourceItem["quote"] = $quoteInitiation
                        $dataSourceItem["Link"] = ""
                        $dataSourceItem.Editing.EndEdit()
                        #$item = Get-Item -Path "master:$($dataSourceItem.FullPath)"
                        Publish-Item -Path "master:$($dataSourceItem.FullPath)" -PublishMode Smart -Target Edge
                        # Datasource item fields update - End
                    }
                    else {
                        Write-Host "Unable to process $($dataSourceItem.FullPath)"
                    }
                }    
       
                $defaultProductOptionItemId = "{Exxxx8D-5DD0-4188-ABED-5Axxxxx56}";
                if ([string]::IsNullOrEmpty($pageItem["prodOption"])) {
                    $pageItem.Editing.BeginEdit()
                    $pageItem["prodOption"] = $defaultProductOptionItemId
                    $pageItem.Editing.EndEdit()
                    Publish-Item -Path "master:$($pageItem.FullPath)" -PublishMode Smart -Target Edge
                }
           
            }
            catch [System.Net.WebException], [System.IO.IOException] {
                Write-Host "Unable to process item " $pageItem.FullPath
            }

            $pageItem
        }
    }
}
$items = ProcessProductLocationPage_Auto

if ($items.Count -eq 0) {
    Write-Host "Nothing found."
}
else {
    $props = @{
        InfoTitle       = "Quote Initiation."
        InfoDescription = "Your description here."
        PageSize        = 25
    }

    $items |
    Show-ListView @props -Property @{Label = "Name"; Expression = { $_.DisplayName } },
    @{Label = "Id"; Expression = { $_.Id } },
    @{Label = "Template Name"; Expression = { $_.TemplateName } },
    @{Label = "Path"; Expression = { $_.ItemPath } }
}

Write-Host "Script execution completed!"


Thanks!

Troubleshoot personalization on xm cloud

Here are the troubleshooting steps below that helped personalization to work. We checked the events analytics in the page builder but it was...