Salesforce Stack Exchange is a question and answer site for Salesforce administrators, implementation experts, developers and anybody in-between. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

Is there a way to get the URL of a salesforce site from apex

I need this to send the url in an email message, so the apex is run outside of the site context. I basically want to expose a link to my salesforce site in an email message. But so far I haven't found a way to do that

I would prefer not hard coding the url in apex

share|improve this question
Are Sites available in some table you can query? Like select NamespacePrefix, Name from ApexPage limit 10? – eyescream Jan 24 '13 at 17:29
yes, you can query them: [SELECT Name, Status, Subdomain FROM Site] this only gives me the subdomain in, this should work well when installed on a production org, but when using the app on a dev org / sandbox you get a different URL for example: – pjcarly Jan 24 '13 at 17:35
I just posted an idea on the IdeaExchange to make this easier to do. Please vote! – Benj Oct 3 '13 at 0:57
Great idea, voted Benj. – greenstork Oct 3 '13 at 3:22


But with some cunning, you can extract this from the site debug mode endpoint:

String name = 'mysite';

Site site = [
    SELECT GuestUserId
    FROM Site
    WHERE Name = :name

String path = '/sites/servlet.SiteDebugMode';
PageReference pr = new PageReference(path);
pr.getParameters().put('guid', site.GuestUserId);
pr.getParameters().put('sitedebugmode', 'x');
String url = pr.getContent().toString().substringAfter('URL=').substringBefore(path);

System.debug(url); //eg ""

Seems to behave across environments regardless of Production / Sandbox / My Domain etc.

share|improve this answer
What a beautiful hack-y solution, upvote, but I'm not going to use it any time soon in our AppExchange apps, I find it just a little too tricky. – pjcarly Oct 15 '15 at 15:08
glad you like it @pieterjancarly :-) lemme put that disclaimer up front – bigassforce Oct 15 '15 at 17:41
up vote 6 down vote accepted

This doesn't seem to be possible from apex, I ended up trying the different ways described above, and decided to go with a Custom Setting. I added the Custom Setting Site URL which needs to be filled in every time when the app gets configured.

share|improve this answer

This used to work. I didn't tested it recently, try it out.

Site s = [SELECT s.Subdomain FROM Site s LIMIT 1 ];
String urlCode = String.valueof(URL.getSalesforceBaseUrl().toExternalForm());
String [] cuts = urlCode.split('[.]');
urlCode = '';
for(Integer i = 1; i < cuts.size(); i++){
        urlCode += cuts[i] + '.';
urlCode = urlCode.substring(0, urlCode.length()-1);  
urlCode = 'https://'+s.Subdomain+'.'+urlCode+'/yourpage;
share|improve this answer
I'll give it a try, and keep you posted, thanks for the code! – pjcarly Jan 24 '13 at 22:12
unfortunately this doesn't seem to give me the correct site address on a developer org, but will probably work on a production org though – pjcarly Jan 25 '13 at 13:26
Is that because DE orgs have the "-developer" portion enforced on the URL? – joshbirk Feb 20 '13 at 15:45

If you are looking to associate to a single record, you will need to use the PageReference class. Specifically:




To piece that together you would use the following:

String url = 'https://' + ApexPages.currentPage().getHeaders().get('Host') + ApexPages.currentPage().getHeaders().getUrl();

If you are looking to link to a specific object, you just need the host and the ID of that object. Say you want to link to an account for instance and the account you have is referenced by the acc variable:

String url = 'https://' + ApexPages.currentPage().getHeaders().get('Host') + '/' + acc.Id;
share|improve this answer
I don't have a Page i'm executing from, so there is no Apexpages available, it is run directly from apex. – pjcarly Jan 24 '13 at 16:53
Ah ok. I don't know if there is a way to get the host outside of the Page context. In this scenario, to avoid hard coding a value, I would just create a custom setting and reference that. You can then update that custom setting whenever needed. It is a similar concept to a property file used in other programming languages. – Jesse Altman Jan 24 '13 at 16:56
I know custom settings, but the thing is, i'm trying to write an app, and having to set a custom setting per deployment is quite a hasstle – pjcarly Jan 24 '13 at 17:01

As others have noticed, this isn't currently possible in Apex. I've posted an idea on the IdeaExchange to request that this feature be added. Please consider voting for it!

share|improve this answer
sorry for downvote, but this is not an answer. This is a very good idea, but it is still not an answer – Novarg Mar 31 '15 at 14:17

Here is the solution:

    Site site = [SELECT GuestUserId, Name, Subdomain, UrlPathPrefix FROM Site WHERE Name = :'My Site'];

    Organization org = [SELECT InstanceName, IsSandbox, OrganizationType FROM Organization];

    String siteFullUrl = 'https://' + site.Subdomain + '.';
    siteFullUrl += (org.IsSandbox || org.OrganizationType == 'Developer Edition' ? (org.InstanceName.toLowerCase() + '.') : '') + '';
    siteFullUrl += '/' + site.UrlPathPrefix;
share|improve this answer
For sandboxes, the sandbox name gets prefixed onto the URL, like: https://(sandboxname)-(site.Dubdomain).(instancename) ... getting the sandboxname is not easy though. Seems best to take it from end of username. – codeulike Jan 16 at 14:19

Please refer the below link:

seems you might need to make use of

apexpages.currentpage().getURL() and apexpages.currentpages().getHeaders().get('HOST')
share|improve this answer
that's not answering my question, I need the site url like so: '', Site.getCustomWebAddress() keeps returning NULL because it is run from outside the site context – pjcarly Jan 24 '13 at 16:50
String sfdcBaseURL = URL.getSalesforceBaseUrl().toExternalForm();

This should work for your requirement.

share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.