Solving the Conflict Between Keys from Dynamic Placeholder Modules and Coveo Dynamic Placeholders

This page addresses an issue that only happens when using the Coveo for Sitecore Hive framework (see Coveo for Sitecore Hive UI Framework).


When creating a site using Coveo for Sitecore, you rely on placeholders to display different elements on a page.

On a Coveo for Sitecore Hive search page, you see placeholders for the search interface, the search box, the error message, the result list, and all other components needed to build a functional search page. These placeholders are controlled by a dynamic placeholder module which makes them mobile. Coveo for Sitecore comes with the following placeholder method: @Html.Sitecore().CoveoDynamicPlaceholder("coveo-ui-content", @Model.Id). This placeholder module is responsible for displaying an Add here button and a placeholder area to insert the desired components.

The image below shows placeholders to add facet, search box and result list components from the Experience Editor in Coveo for Sitecore.

However, the custom Coveo Dynamic Placeholder uses a key that isn’t compatible with existing dynamic placeholders previously downloaded by users. The Coveo Dynamic Placeholder key follows the [placeholder]_dynamic_[identifier] syntax.

You have a website you created using a platform other than Coveo for Sitecore. To improve search and relevancy on your site, you decide to install Coveo for Sitecore to build a search page. Chances are that you already have a dynamic placeholder module, like the Fortis Collection one. Its dynamic key syntax comes in two parts: [placeholder]_[uniqueId].


Conflicts between keys happen because the Coveo for Sitecore Hive Dynamic Placeholder uses the [placeholder]_dynamic_[identifier] syntax. The [placeholder] part serves as the effective key, and [identifier] as any string.

However, most existing implementations require this format: [placeholder]_[uniqueId]. In this format, [placeholder] is the effective key to use, and [uniqueId ] is any GUID.

For example, with the Fortis Collection dynamic placeholder implementation, the module is triggered when the Coveo Dynamic Placeholder format is read in the page and uses the whole part before the [identifier] part. The key is read as [placeholder]_dynamic which is invalid and matches none of the placeholders on the search page, making them unusable.

When the first placeholder resolver picks a Coveo Dynamic key, it resolves it to aplaceholder_dynamic instead of simply aplaceholder. Since the key of an external Dynamic Placeholder module doesn’t contain dynamic in its format, the search interface placeholders and the module aren’t compatible anymore.


There are a few possible solutions.

Upgrade to the December 2017 version of Coveo for Sitecore

  1. If you have a version of Coveo for Sitecore prior to December 2017 and you’re using or plan on using a dynamic placeholder module, upgrade to December 2017.
  2. If you just upgraded to December 2017:

    1. If you have an existing page, you must migrate your existing pages to the new Coveo for Sitecore format using PowerShell scripts (see Migrating the Data Sources).
    2. If you don’t have an existing page, you can create a new search page without problem.
  3. If you installed for the first time Coveo for Sitecore December 2017, it should work without any additional work.

If you’re using a version of Coveo for Sitecore that’s prior to December 2017 and you don’t want to upgrade it, try this workaround to fix the key conflict between placeholders. You will configure a new regular expression that will ignore the Coveo dynamic placeholders that include the text _dynamic\_, and then match it by the expected GUID pattern.

Migrating the Data Sources

Using this PowerShell Extension script, you can replace all the data sources with the new format.


function Replace-CoveoIdsInDataSources() {
        [Parameter(Position=0, ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)] [Sitecore.Data.Items.Item[]]$items = (Get-ChildItem -Recurse)
    Process {
        $items | Where-Object {
            $_.ItemId -ne $null -and $_.ItemId -ne ""
        } | ForEach-Object {
            $newValue = ($_.ItemId -replace '_([A-Fa-f0-9]{8})[A-Fa-f0-9\-]{28}', 'coveo$1');
            Write-Host "Updating Coveo Data Source `"$($_.FullPath)`" ID from `"$($_.ItemId)`" to `"$newValue`"";
            $_.ItemId = $newValue

This script can be run on any Local Parameters or Global Parameters item that contains data sources for your Coveo Search Interfaces.

Get-ChildItem -Recurse | Replace-CoveoIdsInDataSources

This example migrates all the data sources that are children of the current item.

Migrating the Renderings Placeholder

Since the renderings contain many references to the old format, you also need to migrate the placeholder keys to use the new format.


function Replace-CoveoKeysInPlaceholdersForNewFormat {
        [Parameter(Position=0, ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)] [Sitecore.Data.Items.Item]$item = (Get-Item ".\")
    Process {
        Write-Host "Updating all renderings placeholders for `"$($item.FullPath)`"";
        $item | Get-Rendering -FinalLayout:$FinalLayout | ForEach-Object {
            Set-Rendering -Instance $_ -Item $item -PlaceHolder ($_.Placeholder -replace '_dynamic__?([A-Fa-f0-9]{8})[A-Fa-f0-9\-]{28}', '_dynamic_coveo$1') -FinalLayout:$FinalLayout

This script needs to be run directly on an item that contains Coveo for Sitecore Hive renderings.

Get-Item ".\" | Replace-CoveoKeysInPlaceholdersForNewFormat

This example migrates the renderings placeholders only for the current item. Useful if you want to migrate pages one at a time.

Get-ChildItem -Recurse | Replace-CoveoKeysInPlaceholdersForNewFormat

This example migrates the renderings placeholders for all the children of the current item. Use with caution.