Expand my Community achievements bar.

Experience Fragments & multiple sites

Avatar

Level 1

Hi all, 

We have multiple sites and pages within the sites sharing the same templates, and we understand we need to assign an experience fragment to a template. We are wondering if it is possible, and if so how, to implement more than one experience fragment header on a single template, and direct which pages should use a certain experience header?  

Thank you!

Lauren 

Topics

Topics help categorize Community content and increase your ability to discover relevant content.

3 Replies

Avatar

Community Advisor

While using a editable template, while using experience fragments, the same brand pointing to a locale, for example /content/experience-fragments/brand-a/en/header, the out of the box experience fragment will be smart enough to route the resource to the correct locale, for example /content/brand-a/fr -> /content/experience-fragments/brand-a/fr/header, /content/brand-a/kr -> /content/experience-fragments/brand-a/kr/header, /content/brand-a/it -> /content/experience-fragments/brand-a/it/header.

In previous projects, I had a similar requirement like yours, we had /content/brand-a, /content/brand-b, /content/brand-c using the exact same editable templates. So how did we determine 

  • /content/brand-a/ca/en (points to ->) /content/experience-fragments/brand-a/ca/en/header/master
  • /content/brand-a/ca/fr (points to ->) /content/experience-fragments/brand-a/ca/en/header/master
  • /content/brand-b/ca/en (points to ->) /content/experience-fragments/brand-b/ca/en/header/master
  • /content/brand-b/ca/fr (points to ->) /content/experience-fragments/brand-b/ca/fr/en/header/master
  • /content/brand-c/ca/en (points to ->) /content/experience-fragments/brand-c/ca/en/en/header/master
  • /content/brand-c/ca/fr(points to ->) /content/experience-fragments/brand-c/ca/fr/en/header/master

One Example Quick Solution (Use Context Aware Configuration):

Create an OSGi Configuration Interface > HeaderXFCaConfig.java

@ObjectClassDefinition(name = "Header XF Configuration")
public  HeaderXFConfig {

    @AttributeDefinition(
        name = "Header XF Path",
        description = "Path to the Experience Fragment used as the header"
    )
    String xfHeaderPath();
}

 

2. Model to Resolve XF Dynamically

@Model(adaptables = { Resource.class }, defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL)
public class HeaderXFModel {

    
    private Resource resource;

    
    private ConfigurationBuilder configBuilder;

    public String getHeaderXFPath() {
        HeaderXFConfig config = configBuilder.as(HeaderXFConfig.class);
        return config != null ? config.xfHeaderPath() : null;
    }
}


3. Include XF Dynamically in custom component

<sly data-sly-use.header="com.example.core.models.HeaderXFModel"
     data-sly-resource="${header.headerXFPath @ resourceType='experience-fragment/components/xfpage'}">
</sly>


4. Very Simple Context Aware Solution

  1. Configure Ca Config for:
    1. /content/brand-a/ca/en (points to ->) /content/experience-fragments/brand-a/ca/en/header/master
    2. /content/brand-a/ca/fr (points to ->) /content/experience-fragments/brand-a/ca/en/header/master
    3. /content/brand-b/ca/en (points to ->) /content/experience-fragments/brand-b/ca/en/header/master
    4. /content/brand-b/ca/fr (points to ->) /content/experience-fragments/brand-b/ca/fr/en/header/master
    5. /content/brand-c/ca/en (points to ->) /content/experience-fragments/brand-c/ca/en/en/header/master
    6. /content/brand-c/ca/fr(points to ->) /content/experience-fragments/brand-c/ca/fr/en/header/master

Avatar

Community Advisor

Hi @LaurenDo1 ,

AEM’s Context-Aware Configurations + Model-based dynamic XF rendering allows you to:

Configure XF paths per site/locale.

Dynamically resolve and include the correct header XF at runtime.

Stay flexible as brands/locales grow — no template changes needed.

Step 1: Create OSGi Config Interface

Define XF Path per context (site/locale).

@ObjectClassDefinition(name = "Header XF Configuration")
public @interface HeaderXFConfig {

    @AttributeDefinition(
        name = "Header XF Path",
        description = "Path to the Experience Fragment used as the header"
    )
    String xfHeaderPath();
}

Step 2: Create a Sling Model to Fetch Config

Fetch the configured XF path dynamically.

@Model(adaptables = { Resource.class }, defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL)
public class HeaderXFModel {

    @Self
    private Resource resource;

    @OSGiService
    private ConfigurationBuilder configBuilder;

    public String getHeaderXFPath() {
        HeaderXFConfig config = configBuilder.as(HeaderXFConfig.class);
        return config != null ? config.xfHeaderPath() : null;
    }
}

Step 3: Include XF Dynamically in HTL Component

<sly data-sly-use.headerModel="com.example.core.models.HeaderXFModel"
     data-sly-resource="${headerModel.headerXFPath @ resourceType='experience-fragment/components/xfpage'}">
</sly>

Step 4: Configure CA Config per Site/Locale

In CRXDE or AEM UI, create CA Config folders:

/conf/brand-a/ca/en
/conf/brand-a/ca/fr
/conf/brand-b/ca/en
/conf/brand-b/ca/fr
Assign xfHeaderPath like:

    /conf/brand-a/ca/en → /content/experience-fragments/brand-a/ca/en/header/master

    /conf/brand-b/ca/fr → /content/experience-fragments/brand-b/ca/fr/header/master


Regards,
Amit

Avatar

Level 6

Yes, it’s definitely possible. The solution involves developing a custom XF component that leverages the AEM Core Component Experience Fragment along with the Sling Model Delegation Pattern. By extending your custom Sling Model, you can override the method ExperienceFragment.getLocalizedFragmentVariationPath to encapsulate the logic needed to determine which header XF to load.

For example, you might use a strategy where you take the current page path (e.g.,
/content/project/us/en/site/sample/nested/page.html) and transform it into the corresponding XF path by replacing "/content" with "/content/experience-fragments" (resulting in something like
/content/experience-fragments/project/us/en/site/sample/nested/page/header). If this specific header XF is not available, you can fall back to a default XF path defined at the language or site level (such as
/content/experience-fragments/project/us/en/site/header).

 

Additionally, you can extend this approach to compute the XF path dynamically by traversing up the content hierarchy from the current page until you reach the language node. For instance, using the example provided, you can search for an XF header using the following paths in order of precedence:

  • /content/experience-fragments/project/us/en/site/sample/nested/page/header

  • /content/experience-fragments/project/us/en/site/sample/nested/header

  • /content/experience-fragments/project/us/en/site/sample/header

This hierarchical lookup ensures that if the header XF isn’t found at a deeper level, the system will continue searching in the higher-level directories, ultimately falling back to the default XF path defined at the language or site level.

This custom logic offers you the flexibility to implement multiple XF headers on a single template and precisely control their usage across different sections of your content tree.