11

(This is the opposite question of Get Site URL from apex.)

I'm running Apex in a request on a Site page. URL.getSalesforceBaseUrl().toExternalForm() gives me https://siteprefix.force.com

I want my actual instance URL: https://mydomain.my.salesforce.com or even https://pod.salesforce.com. How can I get it?

0

8 Answers 8

5

Spring '22 solution:

Use the DomainCreator class:

String url = 'https://' + DomainCreator.getOrgMyDomainHostname();

Winter '19 solution:

// works in sites, sandboxes, custom domain, etc
String url = Url.getOrgDomainUrl().toExternalForm();

Prior to this you can leverage the salesforce Identity URL. It was the documented and supported way to obtain the API endpoints without a login or OAuth handshake. It will work for your Site Guest User too.

4
  • Does this work with MyDomain enabled? Also, is there a single endpoint that would work for both sandbox and production calls, or do I need to send to correct endpoint (login vs test) based on which environment the code is running in?
    – Benj
    Commented Feb 20, 2014 at 17:45
  • (Not sure of the answer to my previous query, but investigating it inspired my answer
    – Benj
    Commented Feb 20, 2014 at 17:46
  • 1
    @Benj yes, it works with MyDomain. It returns the MyDomain endpoint (in Sandbox and Developer Editions too) as that's what API consumers are supposed to use AFAIK. Commented Feb 20, 2014 at 17:51
  • @Benj for login vs test you could attempt the callout to one endpoint followed by the other. Tools like AdminBooster use this to get a one-size-fits-all resolver. Commented Feb 20, 2014 at 20:59
13

I recently faced this exact scenario and also found an answer to this. Use this code snippet to get salesforce instance url when working on a site page

ApexPages.currentPage().getHeaders().get('X-Salesforce-Forwarded-To');

Per the documentation:

X-Salesforce-Forwarded-To : The fully qualified domain name of the Salesforce instance that is handling this request. This header is always set on HTTP and HTTPS requests that are initiated outside of Salesforce's data centers.

Related PageReference headers documentation

2

You could use this one as well.

public String getURL() {
    return String.format(
      'https://{0}.salesforce.com',
      new String[]{
        URL.getSalesforceBaseUrl().getHost().substringAfter('.').substringBefore('.')
      });
}
1

I think I'm going to end up using a solution like this:

public String getInstanceUrl(){
   String domain = [Select d.Domain From Domain d where DomainType='DNS' Limit 1].Domain;
   if (domain==null){
       domain=URL.getSalesforceBaseURL().getHost();
   }
   return 'https://'+domain;
}

Essentially, I'm just using this to build a path to /services/apexrest/ so I prefer to just use the domain that I have configured. If for some reason the domain isn't set up, I'll just grab the Salesforce base url.

2
  • I hadn't even known about the Domain object, that's a nice touch. But when I query against Domain, I'm still only getting external/Sites URLs -- nothing with the Salesforce internal URL :(
    – Benj
    Commented Feb 13, 2014 at 21:25
  • 1
    Yeah, I found out this didn't work perfectly for my solution either. I ended up taking the standard lazy SFDC developer route and making a custom setting to store the url in...
    – Claude
    Commented Feb 19, 2014 at 16:06
1

This isn't an exact answer to my question, but it solved my needs in this case. Instead of using the specific mydomain id, I found that I could get by with a generic reference to login.salesforce.com (for production) or test.salesforce.com (for sandboxes).

As such, the following was a close-enough approximation:

public String getInternalUrl() {
    String host = URL.getSalesforceBaseURL().getHost();

    // if host has a token of form csXX or tapp0, it's a sandbox
    if (host.contains('cs') || host.contains('tapp')) {
        return 'https://test.salesforce.com';
    } else {
        return 'https://login.salesforce.com';
    }
}
2
  • 1
    I don't see how this answers the original question...
    – max
    Commented Feb 20, 2014 at 17:54
  • Fair. I accepted it b/c it turned out I didn't actually need the actual pod after all - the generic login endpoint turned out to be enough. But I'll unaccept in hopes of a better answer coming in the future!
    – Benj
    Commented Feb 20, 2014 at 20:34
1

I had the exact same problem and was able to solve for this by querying the Organization object and building the URL manually. Eg.

String orgInstance = [SELECT InstanceName FROM Organization][0].InstanceName; // Returns CS17 for example.

String instanceUrl = 'https://' + orgInstance.toLowerCase() + '.salesforce.com';

This will return the instance URL, regardless if accessed from external site.

0

You should use this:

String currentRequestURL = URL.getCurrentRequestUrl().toExternalForm();

This will return complete URL into String form with all parameters and structure.

Referenced: URL Class

1
  • 1
    This doesn't work. Trying this right now yields siteprefix.force.com/site/apex/PageName which is the Site URL, NOT the internal URL I've requested.
    – Benj
    Commented Feb 13, 2014 at 13:49
0

Try this URL class

System.URL.getSalesforceBaseURL().getHost();
1
  • 1
    This doesn't work (it's effectively the same thing as the example in my OP). Trying this right now yields siteprefix.force.com which is the Site URL, NOT the internal URL I've requested.
    – Benj
    Commented Feb 13, 2014 at 13:49

You must log in to answer this question.

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