40

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

4
  • Are Sites available in some table you can query? Like select NamespacePrefix, Name from ApexPage limit 10?
    – eyescream
    Commented Jan 24, 2013 at 17:29
  • 1
    yes, you can query them: [SELECT Name, Status, Subdomain FROM Site] this only gives me the subdomain in subdomain.force.com, 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: http://subdomain.na14.force.com/sitename
    – pjcarly
    Commented Jan 24, 2013 at 17:35
  • 2
    I just posted an idea on the IdeaExchange to make this easier to do. Please vote!
    – Benj
    Commented Oct 3, 2013 at 0:57
  • Great idea, voted Benj.
    – greenstork
    Commented Oct 3, 2013 at 3:22

10 Answers 10

30

Since Winter '17 (v38.0)

You can get the secureURL using the SiteDetail object

Site mySite = [select Id from Site where Name = 'MySite'];
SiteDetail mySiteDetail = [select SecureURL from SiteDetail where DurableId = :mySite.Id];
System.debug(mySiteDetail.SecureURL);
4
  • 2
    I previously went with the solution of querying the description field, but this is definitely an improvement over that IMO. Nice one!
    – Matt Lacey
    Commented Mar 29, 2019 at 2:37
  • 2
    I think this answer should be marked as best answer
    – Ariel
    Commented Jan 18, 2020 at 9:34
  • As of 2020-02-13, it's too bad one can't do a join query to get the SecureUrl, e.g. SELECT Id, SecureUrl FROM SiteDetail WHERE DurableId IN (SELECT Id FROM Site WHERE UrlPathPrefix = 'myPrefix') Commented Feb 13, 2020 at 15:40
  • As of Summer 21 I've had to switch all my clients to this approach. I previously used the site debug mode hack described below, but now it's giving this error: core.apexpages.exceptions.ApexPagesGenericException: "500 status code return from request to na135.salesforce.com/sites/…" Commented Jun 9, 2021 at 3:29
6

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.

1
  • 1
    that's simply wrong - at least today. URL.getSalesforceBaseUrl().toExternalForm() returns the complete org-url. Commented Sep 28, 2016 at 16:07
4

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() + '.') : '') + 'force.com';
    siteFullUrl += '/' + site.UrlPathPrefix;
2
  • 1
    For sandboxes, the sandbox name gets prefixed onto the URL, like: https://(sandboxname)-(site.Dubdomain).(instancename).force.com/(urlPathPrefix) ... getting the sandboxname is not easy though. Seems best to take it from end of username.
    – codeulike
    Commented Jan 16, 2016 at 14:19
  • The solution from @bigassforce had worked beautifully for a while, but when we added new non-admin licensing types the process began to fail. This solution works well, thank you.
    – user52918
    Commented Jul 17, 2018 at 16:29
3

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++){
    if(!cuts[i].contains('visual')){
        urlCode += cuts[i] + '.';
    }
}     
urlCode = urlCode.substring(0, urlCode.length()-1);  
urlCode = 'https://'+s.Subdomain+'.'+urlCode+'/yourpage;
3
  • I'll give it a try, and keep you posted, thanks for the code!
    – pjcarly
    Commented Jan 24, 2013 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
    Commented Jan 25, 2013 at 13:26
  • Is that because DE orgs have the "-developer" portion enforced on the URL?
    – joshbirk
    Commented Feb 20, 2013 at 15:45
3
String sfdcBaseURL = URL.getSalesforceBaseUrl().toExternalForm();

This should work for your requirement.

2

A quick hack if you don't want to create a custom setting just to store the url is to use the description field on the site to store the URL address. Then just query the site based on the Name or MasterLabel.

string siteUrl = [SELECT Description FROM Site WHERE MasterLabel = 'Site Name'].Description;

You can still store a general description in the field, you'll just want to wrap your URL in a distinct tag character and then use String.substringBetween(tag).

For example if your description was "This is my super cool site for promoting super cool stuff ~myCustomSiteURLAddress~". You could then get just the url by querying...

string siteUrl = [SELECT Description FROM Site WHERE MasterLabel = 'Site Name'].Description.substringBetween('~');

1

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

ApexPages.currentPage().getHeaders().get('Host');

and

ApexPages.currentPage().getHeaders().getUrl();

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;
3
  • I don't have a Page i'm executing from, so there is no Apexpages available, it is run directly from apex.
    – pjcarly
    Commented Jan 24, 2013 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. Commented Jan 24, 2013 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
    Commented Jan 24, 2013 at 17:01
1

For using some of the above mentioned answers, I believe it is required to enable the site object in your org. For me it was not available and this was the best possible solution I could have.

String sfdcBaseURL = URL.getSalesforceBaseUrl().toExternalForm();

0

Please refer the below link:

http://boards.developerforce.com/t5/Apex-Code-Development/Get-Current-Page-URL-in-Apex-Class-Full-amp-Exact-URL/td-p/134623

seems you might need to make use of

apexpages.currentpage().getURL() and apexpages.currentpages().getHeaders().get('HOST')
1
  • 1
    that's not answering my question, I need the site url like so: 'https://mysaleforceorg.force.com/', Site.getCustomWebAddress() keeps returning NULL because it is run from outside the site context
    – pjcarly
    Commented Jan 24, 2013 at 16:50
0

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!

https://success.salesforce.com/ideaView?id=08730000000kvysAAA

1
  • sorry for downvote, but this is not an answer. This is a very good idea, but it is still not an answer
    – Novarg
    Commented Mar 31, 2015 at 14:17

You must log in to answer this question.

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