The managed java bean package org.openntf.breadcrumb; import java.util.ArrayList; import java.util.List; import com.ibm.xsp.extlib.tree.ITreeNode; import com.ibm.xsp.extlib.tree.complex.AbstractComplexTreeNode; import com.ibm.xsp.extlib.tree.impl.TreeUtil; import org.openntf.breadcrumb.Entry; public class BreadCrumbSessionFacade extends AbstractComplexTreeNode { /** * */ private static final long serialVersionUID = 1L; private List<ITreeNode> m_BreadCrumbs; public void addEntry(String strURL, String strParams, String strName) { if (m_BreadCrumbs == null) { m_BreadCrumbs = new ArrayList<ITreeNode>(); } int nDel = -1; int nCount = -1; for (ITreeNode itCurrent : m_BreadCrumbs) { nCount++; Entry entCurrent = (Entry) itCurrent; if (entCurrent.getBreadCrumbName().equals(strName)) { nDel = nCount; entCurrent.setURL(strURL); entCurrent.setParameter(strParams); break; } } if (nDel > -1 && nDel < (m_BreadCrumbs.size() - 1)) { m_BreadCrumbs = m_BreadCrumbs.subList(0, nDel + 1); } if (nDel == -1) { Entry entNew = new Entry(); entNew.setURL(strURL); entNew.setBreadCrumbName(strName); entNew.setParameter(strParams); m_BreadCrumbs.add(entNew); } int nCounter = 1; for (ITreeNode eb : m_BreadCrumbs) { if (nCounter == m_BreadCrumbs.size()) { ((Entry) eb).setEnabled(false); } else { ((Entry) eb).setEnabled(true); } nCounter++; } } public int getType() { return NODE_CONTAINER; } public NodeIterator iterateChildren(int start, int count) { return TreeUtil.getIterator(m_BreadCrumbs, start, count); } public void reset() { m_BreadCrumbs = null; } } The Entry: package org.openntf.breadcrumb; import java.io.Serializable; import com.ibm.xsp.extlib.tree.complex.AbstractComplexTreeNode; public class Entry extends AbstractComplexTreeNode implements Serializable{ /** * */ private static final long serialVersionUID = 1L; private String m_URL; private String m_BreadCrumbName; private String m_Parameter; private boolean m_Enabled = true; public void setURL(String uRL) { m_URL = uRL; } public String getURL() { return m_URL; } public void setBreadCrumbName(String breadCrumbName) { m_BreadCrumbName = breadCrumbName; } public String getBreadCrumbName() { return m_BreadCrumbName; } public int getType() { return NODE_LEAF; } public NodeIterator iterateChildren(int start, int count) { return null; } @Override public String getHref() { //System.out.println(m_URL +"?"+ m_Parameter); return m_URL + m_Parameter; //return m_URL +"?"+ m_Parameter; } @Override public String getLabel() { return m_BreadCrumbName; } public void setParameter(String parameter) { m_Parameter = parameter; } public String getParameter() { return m_Parameter; } @Override public boolean isEnabled() { return m_Enabled; } public void setEnabled(boolean enabled) { m_Enabled = enabled; } } Register the Managed bean in the faces-config.xml <?xml version="1.0" encoding="UTF-8"?> <faces-config> <managed-bean-name>breadCrumbBean</managed-bean-name> <managed-bean-class>org.openntf.breadcrumb.BreadCrumbSessionFacade</managed-bean-class> <managed-bean-scope>session</managed-bean-scope> </managed-bean> <!--AUTOGEN-START-BUILDER: Automatically generated by IBM Lotus Domino Designer. Do not modify.--> <!--AUTOGEN-END-BUILDER: End of automatically generated section--> </faces-config> Define the breadCrum in a custom control and add this control to the ApplicationLayout: <?xml version="1.0" encoding="UTF-8"?> <xp:view xmlns:xp="http://www.ibm.com/xsp/core" xmlns:xe="http://www.ibm.com/xsp/coreex"> <xp:panel> <xe:breadCrumbs id="breadCrumbs"> <xe:this.treeNodes> <xe:beanTreeNode nodeBean="breadCrumbBean"></xe:beanTreeNode> </xe:this.treeNodes> </xe:breadCrumbs> </xp:panel> </xp:view> On Each Page do in the beforeRenderResponse Event: <xp:this.beforeRenderResponse> <![CDATA[#{javascript://add the current Page to the breadCrumbBean var strBreadCrumbLabel = "The Title of this Page in the BreadCrumb"; breadCrumbBean.addEntry(""+context.getUrl().getPath(), ""+context.getUrl().getQueryString(), strBreadCrumbLabel); }]]> </xp:this.beforeRenderResponse> If your Page is a ROOT Page, witch means, that your page should reset the BreadCrumbPath call breadCrumbBean.reset() in the beforRenderResponse Event