Skip to main content

SitecoreAI Page Designs, Partial Designs and the local: vs page: Datasource Problem

One of the things I like about SitecoreAI is that you can build a fairly sophisticated page composition model using Page Designs, Partial Designs and Page Branches.

But when you start combining all three, there are a few concepts that are easy to misunderstand.

I recently worked through one such scenario where we were setting up Page Designs and Partial Designs and ran into questions around:

  • Template to Design Mapping
  • Page Design standard values
  • Page Branch insert options
  • Partial Design datasource locations
  • local:/ versus page:/
  • Editing datasource content on individual pages

Individually, each feature makes sense. The confusion starts when they are used together.

The Page Design Structure

Our intended structure was something like this:

Page Template
      |
      v
  Page Design
      |
      +-- Header Partial Design
      |
      +-- Content Partial Design
      |       |
      |       +-- Hero Banner
      |
      +-- Footer Partial Design

The idea was that the Page Design would define the overall page structure, while Partial Designs would contain reusable sections.

For example, a Hero Banner Partial Design could contain:

Hero Banner
├── Title
├── Image
└── Description

We would then reuse that Partial Design across different Page Designs.

Question 1: How Does Template to Design Mapping Actually Work?

One of my initial assumptions was that assigning a Page Design to a template through the Page Builder would update the Page Design field on the template's standard values.

That wasn't what happened.

The Sitecore support response clarified an important distinction.

The assignment updates the Template to Design Mapping under:

/sitecore/content/<siteCollection>/<site>/Presentation/Page Designs

It does not automatically update the Page Design field on the template's standard values.

The mapping is used when the Page Design field on the page is empty.

So conceptually:

Page Design field on page
        |
        |-- has value --> use that Page Design
        |
        |-- empty ------> use Template to Design Mapping

This was an important distinction because it means the Template to Design Mapping isn't redundant. It provides the mapping mechanism when a page doesn't explicitly specify a Page Design.

Then We Hit the Datasource Problem

The more interesting problem was with Partial Designs.

Our Partial Design contained a Hero Banner with a datasource.

Initially, the datasource path used:

page:/Data

The reason for doing this was straightforward.

We wanted the datasource to be local to the actual page.

For example:

/sitecore/content/NHP/Shared/Home/Blog
    |
    +-- Data
        |
        +-- Content Page Hero Banner Text 1

The expectation was that when a content author created a page, they would be able to edit that page's own Hero Banner datasource.

That part worked conceptually.

But there was a problem.

Page Design Preview Stopped Showing Content

When we opened the Page Design itself in Page Builder, the Partial Design didn't show its content correctly.

That made sense once we looked at what page:/ actually means.

The page: prefix tells SitecoreAI to look for the datasource under the current page.

But a Page Design isn't an actual content page.

There isn't necessarily a specific page item underneath which Sitecore can find:

page:/Data/Content Page Hero Banner Text 1

So the datasource cannot be resolved in the same way it can when the Partial Design is being rendered as part of an actual page.

The result was that the Partial Design could appear correctly when viewed independently, but the Page Design preview didn't have the expected datasource content.

Trying local:/Data

The obvious next experiment was to change the datasource path to:

local:/Data

That immediately changed the behaviour.

The Partial Design displayed correctly when used inside the Page Design.

But now we had another problem.

The datasource was coming from the Partial Design itself.

So instead of having:

Page A
└── Data
    └── Hero Banner Datasource

and:

Page B
└── Data
    └── Hero Banner Datasource

we were effectively using the datasource located under the shared Partial Design.

That meant the content was no longer naturally page-specific.

And that was exactly what we were trying to avoid.

So Which Prefix Is Correct?

This was the key clarification from Sitecore Support.

The answer is: it depends on where the datasource is supposed to live.

For a Partial Design, local: means the datasource is resolved relative to the Partial Design.

page: means SitecoreAI should look for the datasource under the actual page.

Prefix Datasource location Typical use
local: Under the Partial Design Shared/reusable Partial Design content
page: Under the current page Page-specific datasource content

Sitecore's explanation was that Partial Designs are intended to be reusable across multiple pages. Therefore, a Partial Design should not be designed around the datasource of one particular page.

When local: Is the Right Choice

Suppose we have this Partial Design:

/sitecore/content/NHP/Shared/Presentation/
    Partial Designs/
        Content Pages/
            Shared/
                Content Page Hero Banner
                    Data/
                        Content Page Hero Banner Text 1

If the Hero Banner is intended to use the datasource associated with that Partial Design, then:

local:/Data

is the appropriate approach.

The Partial Design owns the content.

This makes sense for content that is shared across multiple pages.

When page: Is the Right Choice

Now consider a completely different requirement.

Suppose we have:

/sitecore/content/NHP/Shared/Home/Blog
    |
    +-- Data
        |
        +-- Content Page Hero Banner Text 1

and we want the Hero Banner to use that datasource specifically for the Blog page.

Then:

page:/Data

makes sense.

The datasource belongs to the page, not the Partial Design.

This is what allows content authors to have different Hero Banner values on different pages.

But There Is an Important Catch

If the Partial Design is using page:/, the Page Design itself may not be able to display the datasource content correctly in Page Builder.

Why?

Because the Page Design isn't tied to a particular content page.

There is no specific page from which SitecoreAI can resolve:

page:/Data

This creates an important distinction between:

  • designing a reusable Partial Design
  • previewing a Page Design
  • rendering the final content page

They don't necessarily have the same datasource context.

The Mental Model That Helped Me

The easiest way I found to think about this is:

local:
"I belong to this design."

page:
"I belong to the page using this design."

Once you think about the prefixes this way, the behaviour becomes much less mysterious.

If the content is part of the reusable design itself, local: is appropriate.

If the content is supposed to be authored independently for each page, page: is appropriate.

And Then There Was Page Branches

At the same time, we were setting up Page Branches to allow authors to create pages using predefined structures.

This introduced another part of the architecture:

Template
   |
   v
Template to Design Mapping
   |
   v
Page Design
   |
   +-- Partial Designs
   |
   +-- Components
   |
   +-- Datasource context
   |
   v
Page Branch
   |
   v
Actual content page

Each layer has a different responsibility.

That became particularly important when troubleshooting Page Branch insert options as well.

The Page Branch rule controls whether the branch is available as an insert option. The Template to Design Mapping determines which Page Design should be used when the page does not already have one assigned. And the datasource prefix determines where the component looks for its content.

One More Important Detail: Don't Mix Issues in One Support Case

This investigation also taught me something about working with Sitecore Support.

During the investigation, we had multiple related questions around Page Branches, Page Designs and Partial Designs.

Sitecore Support recommended keeping separate issues in separate support cases so that each problem can be investigated and tracked independently.

In fact, a separate case was created for the Page Branch insert-options problem, while the current case focused on the Partial Design rendering issue.

This is particularly useful with Sitecore because several seemingly related symptoms can actually come from completely different parts of the platform.

The Final Architecture

After going through the support investigation, the architecture became much clearer.

For reusable Partial Design content:

Partial Design
└── Data
    └── Shared datasource

Rendering
└── local:/Data

For page-specific content:

Content Page
└── Data
    └── Page-specific datasource

Rendering
└── page:/Data

The choice isn't about which prefix is "better". It is about deciding who owns the content.

What I Took Away From This

There were three things I found particularly useful from this investigation.

1. Template to Design Mapping is not the same as setting the Page Design field on standard values.

The mapping provides the Page Design when the page's Page Design field is empty.

2. local: and page: define different datasource contexts.

local: points into the Partial Design, while page: points into the actual content page.

3. Page Design preview and actual page rendering don't necessarily have the same datasource context.

A datasource that makes perfect sense when rendering an actual page may not be resolvable when previewing the Page Design itself, because the Page Design isn't tied to a specific page.

Conclusion

Page Designs and Partial Designs give you a powerful way to build reusable page structures in SitecoreAI, but datasource context becomes important as soon as you want content to be editable at the page level.

The most important question to ask isn't simply:

Should I use local: or page:?

The better question is:

Who owns this datasource — the reusable design or the individual page?

If the Partial Design owns it, local: makes sense.

If the page owns it, page: makes sense.

Understanding that distinction makes the behaviour of Page Designs, Partial Designs and Page Builder much easier to reason about.


This post is based on a Sitecore Support investigation into Template to Design Mapping, Page Designs, Partial Designs and datasource context in SitecoreAI.

Comments

POPULAR POSTS

Sitecore PowerShell Script to create all language versions for an item from en version

  We have lots of media items and our business wants to copy the data from en version of media item to all other language versions defined in System/Languages. This ensures that media is available in all the languages. So, we created the below powershell script to achieve the same -  #Get all language versions defined in System/Languages $languages = Get-ChildItem /sitecore/System/Languages -recurse | Select $_.name | Where-Object {$_.name -ne "en"} | Select Name #Ensuring correct items are updated by comparing the template ID  $items = Get-ChildItem -Path "/sitecore/media library/MyProjects" -Recurse | Where-Object {'<media item template id>' -contains $_.TemplateID} #Bulk update context to improve performance New-UsingBlock (New-Object Sitecore.Data.BulkUpdateContext) { foreach($item in $items){    foreach($language in $languages){ $languageVersion = Get-Item -Path $item.Paths.Path -Language $language.Name #Check if language versi...

Export Sitecore media library files to zip using SPE

If you ever require to export Sitecore media files to zip (may be to optimize them), SPE (Sitecore Powershell Extension) has probably the easiest way to do this for you. It's as easy as the below 3 steps -  1. Right click on your folder (icons folder in snap)>Click on Scripts> Click on Download 2. SPE will start zipping all the media files placed within this folder. 3. Once zipping is done, you will see the Download option in the next screen. Click Download Zip containing the media files within is available on your local machine. You can play around with the images now. Hope this helps!! Like and Share ;)

Make Sitecore instance faster using Roslyn Compiler

When we install the Sitecore instance on local, the first load is slow. After each code deploy also, it takes a while for the Sitecore instance to load and experience editor to come up. For us, the load time for Sitecore instance on local machines was around 4 minutes. We started looking for ways to minimize it and found that if we update our Web.config to use Roslyn compiler and include the relevant Nugets into the project, our load times will improve. We followed the simple steps - Go to the Project you wish to add the NuGet package and right click the project and click 'Manage NuGet Packages'. Make sure your 'Package Source' is set to nuget.org and go to the 'Browse' Tab and search Microsoft.CodeDom.Providers.DotNetCompilerPlatform. Install whichever version you desire, make sure you note which version you installed. You can learn more about it  here . After installation, deploy your project, make sure the Microsoft.CodeDom.Providers.DotNetCompilerPlatform.d...

Experience of a first time Sitecore MVP

The Journey I have been working in Sitecore for almost 10 years now. When I was a beginner in Sitecore, I was highly impressed by the incredible community support. In fact, my initial Sitecore learning path was entirely based on community written blogs on Sitecore. During a discussion with my then technology lead Neeraj Gulia , he proposed the idea that I should start giving back to developer community whenever I get chance. Just like I have been helped by many developers via online blogs, stackoverflow etc., I should also try to help others. Fast forward a few years and I met  Nehemiah Jeyakumar  (now an MVP). He had a big archive of his technical notes in the form Sitecore blogs. I realized my first blog dont have to be perfect and it can be as simple as notes to a specific problem for reference in future. That's when I probably created my first blog post on Sitecore. At that time, I didn't knew about the Sitecore MVP program. Over the years, I gained more confidence to writ...

Clean Coding Principles in CSharp

A code shall be easy to read and understand. In this post, I am outlining basic principles  about clean coding after researching through expert recommended books, trainings and based on my experience. A common example to start with is a variable declaration like - int i  The above statement did not clarify the purpose of variable i. However,  the same variable can be declared as -  int pageNumber The moment we declared the variable as int pageNumber, our brain realized that the variable is going to store the value for number of pages. We have set the context in our brain now and it is ready to understand what the code is going to do next with these page numbers. This is one of the basic advantages of clean coding. Reasons for clean coding -  • Reading clean code is easier - Every code is revisited after certain amount of time either by the same or different developer who created it. In both the cases, if the code is unclean, its difficult to understand and u...