The result should look something like this

Salesforce Communities: Visualforce Header on Standard Pages without IFrames

The out-of-the-box Communities setup allows you to add a custom header and footer to your standard pages. However, the the header can only be an image file or HTML file and the footer needs to be HTML. What is additionally complicated is that these files must uploaded as a Document object, so it cannot be managed like regular code, and a new version cannot be uploaded while set in the Community Branding section. What do you do if you want to use standard pages, but need to dynamically show some information in the header based on the user, or if you want to use the same header style on both standard pages and visualforce templates and only want to maintain one version?

Enter the Visualforce injection pattern.

The basic concept is add some Javascript to the HTML header that will call a visualforce page and inject that into the standard page. We will put the header items in a Visualforce Component, that way we can reuse it on Visualforce templates if we need to in the future. This example is overly simplistic, but designed to just demonstrate the concept.

<apex:component controller="CCHeaderController">
	<apex:outputPanel id="ccHeader" layout="block" style="margin:40px;">
		<apex:outputText value="Hello {!userName}!" />
	</apex:outputPanel>
</apex:component>
public with sharing class CCHeaderController {
	
	public String userName {get; set;}
	
	public CCHeaderController() {
		userName = UserInfo.getName();	
	}
}
<apex:page showHeader="false" standardStyleSheets="false">
	<c:CCHeader />
</apex:page>
<script>
	var xmlhttp;
	if (window.XMLHttpRequest) { // code for IE7+, Firefox, Chrome, Opera, Safari
	    xmlhttp=new XMLHttpRequest();
	} else { // code for IE6, IE5
	    xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
	}
	xmlhttp.onreadystatechange = function() {
	    if (xmlhttp.readyState==4 && xmlhttp.status==200) {
	        document.write(xmlhttp.responseText);
	    }
	}
	xmlhttp.open("GET","/customer/CCStandardHeader",false);
	xmlhttp.send();
</script>
<div class="cc_body">

You will need to change the /customer path to whatever you have for your community. Also we have added the open div tag so we can wrap the rest of the standard document body. We can close this with the HTML file used in the Community footer file.

The result should look something like this

The result should look something like this

You can also add actions into your controller

<apex:component controller="CCHeaderController">
	<apex:outputPanel id="ccHeader" layout="block" style="margin:40px;">
		<apex:outputText value="Hello {!userName}!" />
                <apex:form >
		       <apex:commandButton value="Change Name" action="{!changeName}" rerender="ccHeader" />
	        </apex:form>
        </apex:outputPanel>
</apex:component>
public with sharing class CCHeaderController {
	
	public String userName {get; set;}
	
	public CCHeaderController() {
		userName = UserInfo.getName();	
	}

        public PageReference changeName() {
		userName = 'Another Name';
		return null;
	}
}
After clicking the button

After clicking the button

There you go. I have to admit I have not tested the IE5 and IE6 part to see how well it works there, but my guess is that if your users are using IE5 or IE6, you have bigger problems to worry about.

8 Comments on "Salesforce Communities: Visualforce Header on Standard Pages without IFrames"

  • This is very cool, thanks for posting. I’ve been trying to figure out how we could have a dynamic client logo in the header based on the partner that has logged in – this looks like it could do the trick!

    • Niki – That’s definitely how people handle that requirement: by calling out to dynamically-generated HTML or CSS from the static header. But when you do that, be careful of scale. Dynamic calls on every page refresh could get troublesome from a performance perspective. Use cache tags wisely.

  • I have used this technique in a community footer to open a VF page but I’m finding that on the Content and Libraries tabs I am now ONLY seeing the footer and nothing else – no header, tabs or pages! I’ve had trouble with styling with these specific tabs before – have you seen this with your VF header trick on these 2 tabs?

  • Nice solution and allows me to easily display some Contact and Account information of logged on community user. There is one thing though that has me stumped. What is the control that is hidden behind the ‘Create New…’ link in the final image of your solution. You can just see the right edge of this hidden control. I have the same thing in my community and can’t find a way to identify or remove it.

  • This seems to cause a styling issue in the left nav, see that overlap behind the ‘create new’? has anyone been able to address?

  • Just thought I’d weigh in after banging my head against my desk for an hour or so.

    This worked perfectly for me, with the exception of a smattering of JS errors in < IE9. If you are going to be using jQuery in your dynamic header component include the script call before making your XMLHttpRequest, otherwise you will get '$ not defined'.

    I hope this saves someone some time. Other than than this approach of using a dynamic header seem to work perfectly. Thanks!

Leave a Reply