A few weeks ago I was asked to do some generic implementation of ReactJS renderings in Sitecore SXA. The challenges: It needs to work with standard SXA, using dynamic placeholders, using an ORM mapper like Glass but also pass only needed data structures to the components, thus the serialization may not be too bloated. During this journey I found an interesting issue you might get into as well.
So what happened? My placeholders did not show up in my component. One component had one, the other did not. What went wrong?! They used the same codebase in the controller and same client code in the front-end. Could it be code? Could it be a bug?!! It was driving me crazy! It felt like....
Setting up the ReactJS scaffolding
As you may have read in one of my posts Tuning Sitecore Experience Accelerator (SXA) with React.Net it is quite easy to have your own components included in SXA having placeholders where you can add additional components. And you want them to be dynamic. That means that under the hood a Guid is added to the name of the placeholder. This way when you re-use the component they do not have the same child components in them.
What we eventually want to have is a component with one or more placeholders. This looks something like this:
But instead I get:
Creating the items
To make it all very easy for you to understand I leave out all code stuff and focus just on the actual problem. The code is simple and handles the creation of dynamic placeholders based on the datasource template of my component.
I start by creating three placeholder settings:
- majesty (my favorite Islay, cheap but good)
These will be the placeholders for my Whisky Component. Additionally we'll have to add the items to a datasource template for this component:
Adding the component to the page
Now that we have all the things in place we can add the component to the page. In the available Renderings section of the SXA Presentation node I've added my component so I can drag it onto my page in the Experience Editor. I select the Component Properties and select the Placeholder Configuration pointing to the keys I need to use. It is a necessity to have placeholder settings in place otherwise they won't show up. For the ease I will not fill the Allowed Controls.
Troubleshooting the dynamic placeholder
In my real environment one component shows the placeholder and the other one doesn't show a placeholder. This component will combine the issue so you already can check yourself where the differences are. First thing that came up to me was that it might have to do something with the code. I attached to the process and found a difference between the placeholder which showed up and a piece of code that did not render the placeholder and notice the property Editable is false:
This was strange because the other placeholders were configured the same way. But was this because of my code? It wasn't. The placeholder is returned from the SitecoreHelper class. And it also shows that editable = false:
Validation of different Sitecore environments
I began to feel a little desperate...
Had it to do something with the Sitecore items? And then it struck me. The placeholder that didn't show up was different than the other two because it has a dash sign:
laphroig-16years. Some crazier even, when removing the digit from the name works too. So a dash followed by a number will render your placeholder ineditable :-) I remember from an earlier version that the dynamic placeholders had a guid in the display name and now in Sitecore 9.0.1 its gone and shows only the name:
So what if I would remove the dash sign from my placeholder?
So I did two things:
- change the key of the placeholder to
- change the value of the placeholder key value for the datasource template for the controller (dynamically getting the placeholders)
All placeholders are showing. You can even use underscore signs, slashes and other signs in your placeholder key names. Using dashes followed by a number just will disable your component.
SXA to the rescue
Next step is to do something different, the right way: use Sitecore SXA.
Sitecore SXA's Placeholder to the rescue
Checking out the code for the placeholder used by SXA there's no difference:
So I checked the key of the placeholder in SXA:
SXA has its own implementation of handling the uniqueness of the selected rendering. Back to the ReactJS rendering with its dynamic placeholder I renamed it to column-1-1. I was pretty sure that this is not going to work because a dash with a number didn't work! But what the...
It works when just having a number and not any trailing words. Also notice the nice guid now in the name. That wasn't here before! The placeholder implementation of SXA is very different. As stated here: When you use dynamic placeholders, you can add the same placeholder name several times. You can do this across multiple renderings, and you can even use the same placeholder multiple times in a single rendering (source: Sitecore).
The resolution is of three options:
- Use the splitters in SXA (they have their own implementation of handling the unique key)
- Building your own unique key implementation like in this example
- Accept the placeholder key name limitation and go with my solution
So avoid dashes with numbers and letters in them, even dashes of water in your whisky! cheers!