Thursday, October 26, 2023

Sitecore SXA - XP navigation bar site resolving

Sitecore Experience Editor - navigation bar site resolving issue


Situation

We inherited a Sitecore 10.2 setup with a number of sites created with old school MVC. Nothing really fancy, just a bunch of sites just as many other solutions probably. The setup is a little weird (just as many "inherited" solutions, right...) and the customer is not used to working in the XP editor. 

When we were asked to add one more site, we decided to go for a headless approach and installed JSS and SXA on the environment. This is all working fine - all sites are running fine and I dare to say the new site is much more towards all best practices. And also introducing the XP editor - especially to add new components to a page. With the SXA extensions that is working like a charm.

Although we noticed one little issue. The navigation bar in the XP editor didn't work as expected. 


We can open a page in the XP editor and it works - the url looks like
https://dev/?sc_mode=edit&sc_itemid=...&sc_lang=en&sc_version=1&sc_site=portal.
But when we then use the navigation bar to go to another page we get an error because the sc_site parameter in the url is wrong:
https://dev/site1/?sc_mode=edit&sc_itemid=...&sc_lang=en&sc_site=site1&sc_ee_fb=false.
When we manually change the sc_site parameter back to "portal" it works. It seems that it takes the first site in the site definition list.


Site configuration

First thing to check is the site configuration. That seemed to be fine - we also checked the SXA Site Manager and that as well was all ok. 

Note here that the mvc sites are in the config (files), the SXA site is configured in Sitecore (items). This makes is tricky to order them.

There is a SiteResolving config section from SXA where you can add sites that should be resolved after the SXA sites. Just to be sure we added all sites to that list in the config:
<siteResolving patch:source="Sitecore.XA.SitesToResolveAfterSxa.config">
  <site name="exm" resolve="after" />
  <site name="website" resolve="after" />
  ....
</siteResolving>
When all sites are added you can see in the SXA Site Manager that the SXA site moved up and that is now our first site.

Unfortunately, that didn't solve our issue. The site resolving in the navigation bar is still wrong. 


The solution

We contacted Sitecore Support. I thought about trying to find the responsible code to see if I could fix it myself - didn't do that as it would take too much time for something that is not convenient but also not blocking. 

And finally none of those options solved it, but well - let's call it luck. I can't remember why I decided to add a targetHostName in the site definition of the new SXA site. But I did - and actually that fixed our issue. The site resolving is working fine now.

We still don't know exactly why and don't want to spend time searching for a root cause but it is solved and might solve a site resolving issue for you as well. If anyone would know the root cause, please do share though.

Wednesday, October 25, 2023

Sitecore EXM - issue with long name emails

 Sitecore EXM - emails with long names

Our customer is using Sitecore Email Experience Manager to send campaigns (e-mails) to their contacts.  We got notified that they had an issue with a specific campaign that was not sending. 

First of all we noticed that the email was completely blocked in the EXM management tool. We could not de-activate it to try to change anything which was pretty weird. Luckily the logs showed us some meaningful information.
ERROR Exception: Sitecore.Exceptions.InvalidItemNameException
Message: An item name lenght should be less or equal to 100.
Source: Sitecore.Kernel
   ....
   at Sitecore.EmailCampaign.Cm.Pipelines.DispatchNewsletter.DeployAnalytics.AddCampaignItem(MessageItem message)

 

An item name lenght should be less or equal to 100

Yes, item length - that is the issue. (including the typo in the exception message 😊)

But what item name? Yes, the name of the email was long, but not that long. EXM does check the length of the name - just try to type more than 100 characters in the name field of a new regular mail and it will turn red. 

Let's have another look at the trace in the error message - it seems to be from "AddCampaign" and that rings a bell. When a regular email is created, Sitecore also creates a campaign item in /sitecore/system/Marketing Control Panel/Campaigns. When we check the names of the items there it seems to be the name of the mail campaign with the item id (guid). This means that this item is 36 characters longer than the mail name - leaving us with only 64 characters for the mail name. 

Which is fine - if you know it. And yes, that should be checked in EXM. You can consider this a bug -it is- but I'm not going to patch a solution for it. 

Fix ?

We could try and patch it ourselves, but it's actually not worth the effort. We could also increase the MaxItemNameLength but again - don't seem worth it. Note that we are talking about the name of the mail campaign, not the subject or anything the end customer would see.

So we decided to just fix the impacted mail and inform the customer to use shorter names in future (until we move the solution to Sitecore Send 😛)

Fixing locked mail items

Fixing the item seemed to be not that easy actually as it was really locked. I could not deactivate it to edit it. An old trick to the rescue, described on Sitecore Stack Exchange (of course... ) in another situation but still very useful. 

Go to the content editor and locate the mail item. Unprotect it and make the changes you want - in this case shorten the title.  Protect the item again - use the "Open EXM" button to go to the item where you now can de-active and activate again.  And that should fix your mail.

Conclusion


One more reason to start moving the mail part of the solution to Send...




Tuesday, October 24, 2023

Sitecore SXA Responsive Image - null reference

 SXA Responsive Image null reference issue

We recently faced an issue on Sitecore SXA with the Responsive Image component. Our customer informed us that if an image was not published pages containing that image would be broken. And not just missing the image - but actually broken. 

The site is running on Sitecore 10.2 using SXA - and the site is patched with the latest hotfix packages so actually running on 10.2.1 (and even 10.2.2 now). On the broken pages we had renderings that use the ootb Responsive Image rendering variant. So it was clear that the issue was with that component.

In the release notes for version 10.3 we found the matching bug: 
If a Responsive Image variant field points to a broken link, a NullReferenceException error occurs.
Upgrading is 10.3 is not an option. So let's try to fix this ourselves. I found the issue in the class Sitecore.XA.Feature.Stylelabs.Pipelines.RenderVariantField.RenderFallbackResponsiveMImage which came with the 10.2.1 update. The RenderField method in that class uses a function called StylelabsDataExtractor.GetSrcAttributeValue. That is weird as this one is deprecated in 10.2 and it mentions to use the new function GetAttributeValue. When I tried the same code with that function the error was gone. 

So let's recap that and show the code you need.
using System.Web.UI;
using Sitecore.Data.Fields;
using Sitecore.Data.Items;
using Sitecore.Web.UI.WebControls;
using Sitecore.XA.Feature.Stylelabs.Services;
using Sitecore.XA.Foundation.Variants.Abstractions.Pipelines.RenderVariantField;

namespace Foundation.Infrastructure
{
    public class RenderFallbackResponsiveMImage : Sitecore.XA.Feature.Stylelabs.Pipelines.RenderVariantField.RenderFallbackResponsiveMImage
    {
        public RenderFallbackResponsiveMImage(IStylelabsDataExtractor stylelabsDataExtractor) : base(stylelabsDataExtractor)
        {
        }

        public override void RenderField(RenderVariantFieldArgs args)
        {
            var variantField = args.VariantField;
            if (args.Item.Paths.IsMediaItem || string.IsNullOrWhiteSpace(variantField?.FieldName))
            {
                base.RenderField(args);
            }
            else if (PageMode.IsExperienceEditorEditing)
            {
                args.ResultControl = (Control)new FieldRenderer()
                {
                    Item = args.Item,
                    FieldName = variantField.FieldName,
                    DisableWebEditing = !args.IsControlEditable
                };
                args.Result = this.RenderControl(args.ResultControl);
            }
            else
            {
                var field1 = args.Item.Fields[variantField.FieldName];
                if (field1 == null)
                {
                    return;
                }

                if ((FieldTypeManager.GetField(field1) is ImageField field2 ? field2.MediaItem : (Item)null) == null)
                {
                    field2 = (ImageField)field1;
                    string srcAttributeValue = this.StylelabsDataExtractor.GetAttributeValue("src", field2);
                    Control fieldRenderer = this.CreateFieldRenderer(args);
                    this.RenderControl(args, fieldRenderer, srcAttributeValue);
                }
                else
                {
                    base.RenderField(args);
                }
            }
        }
    }
}

Note the usage of this.StylelabsDataExtractor.GetAttributeValue("src", field2);

To get this code working instead of the original one we can patch the configs and insert this into the dependency injection:
<sitecore>
  <pipelines>
    <renderVariantField>
      <processor patch:instead="*[@type='Sitecore.XA.Feature.Stylelabs.Pipelines.RenderVariantField.RenderFallbackResponsiveMImage, Sitecore.XA.Feature.Stylelabs']"
				type="Foundation.Infrastructure.RenderFallbackResponsiveMImage, Foundation.Infrastructure" resolve="true" />
    </renderVariantField>
  </pipelines>
</sitecore>


That's it. Don't forget if you ever upgrade to remove this code of course.