I have a Visualforce Page running on a Force.com Site that looks like this:

<apex:page standardController="Page__c" extensions="RootTemplateExtension">
    {!URLFOR($Page.Master, null, ["id"="a00b000000IovF1"])}

And I've got a Site.UrlRewriter implementation that looks like this:

global List<PageReference> generateUrlFor(List<PageReference> salesforceRefs) {
    //TODO bulkify this

    List<PageReference> friendlyRefs = new List<PageReference>();
    for (PageReference salesforceRef : salesforceRefs) {
        String salesforceUrl = salesforceRef.getUrl();
        Map<String,String> salesforceParams = salesforceUrl.getParameters();

        //note URLFOR does not output '/apex' prefix in context of Force.com Sites
        String master = Page.Master.getUrl().replace('/apex', '');

        if (salesforceUrl.startsWith(master) && salesforceParams.containsKey('id')) {
            Id pageId = salesforceUrl.getParameters().get('id');
            Page__c page = [SELECT Id, Name FROM Page__c WHERE Id = :pageId];

            PageReference friendlyRef = new PageReference('/' + page.Name);

    return friendlyRefs;

I've even got a TEST that shows this should work

static testmethod void testGenerateUrlForSummary() {
    //arrange rewriter and page
    Site.UrlRewriter rewriter = new UrlRewriter();
    Page__c page = new Page__c(Name = 'Summary');
    insert page;

    //arrange url ('/ns__Master?id=a01000000000AAA')
    String url = System.Page.Master.getUrl().replace('/apex', ''); //drop prefix
    PageReference salesforceRef = new PageReference(url);
    salesforceRef.getParameters().put('id', page.Id);

    PageReference friendlyRef = rewriter.generateUrlFor(new List<PageReference>{salesforceRef})[0];

    String expectedUrl = '/Summary';
    String actualUrl = friendlyRef.getUrl();
    System.assertEquals(expectedUrl, actualUrl, 'Summary url not generated.');

But for the life of me I can't see it happen in the actual Force.com Site. I've carpet bombed the code with System.debug but all I can eyeball is that startsWith is not true as expected.

Any ideas?

  • 1
    just a suggestion did you try startsWithIgnoreCase? could be a case sensitivity issue?
    – Rao
    Commented Oct 27, 2014 at 17:41
  • Thanks @rao! You are correct, Apex PageReference is generated with lowercase m first letter Commented Oct 27, 2014 at 22:22

1 Answer 1


On a Force.com Site, the implementation of URLFOR() and Page.Master.getUrl() differ:

URLFOR() returns an all-lowercase string without /apex prefix.

PageReference.getUrl returns a first-letter-capitalized string with /apex prefix.

public class UrlForController {
    public String getApexUrl() {
        return Page.MaStEr.getUrl();

<apex:page controller="UrlForController">
        //all lowercase "/master"

        //capitalizes first letter only "/apex/Master"

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .