[ACCEPTED]-Retrieve salesforce instance URL instead of visualforce instance-visualforce

Accepted answer
Score: 11

Here's something that I used within my Apex 1 Trigger

System.URL.getSalesforceBaseUrl().getHost().remove('-api' );

This gives me proper URL

Score: 4

This is a known issue, the URL.getSalesforceBaseUrl() should provide 21 this information but it does not. However 20 in reality this has very limited functional 19 impact.

Their instance and apex domains 18 are interchangeable in the sense that requesting 17 a URL that does not belong to one gets redirected 16 to the other.

for example if you seek /apex/myPage 15 from cs1.salesforce.com you'll get redirected 14 to c.cs1... and vise versa requesting /ID 13 from apex domain will get you redirected 12 to instance domain (unless detail action 11 has been overridden)

If this does not help 10 you there is one workaround, albeit very 9 ugly :) create a custom object to store 8 the base url and create before insert/update 7 trigger which will set the baseURL field 6 to URL.getSalesforceBaseUrl().toExternalForm(). Apparently trigger is the only place 5 on the platform where this will work (aside 4 from execute anonymous which is not of much 3 use). When setting up the app insert something 2 into that table and later use SOQL to retrieve 1 base url.

Score: 4

Here is an Apex property that you can throw 10 into a Utility class that will reliably 9 return the instance for your org. Using 8 this, you can easily construct your organization's 7 Salesforce URL by appending ".salesforce.com" to 6 the Instance:

public class Utils {

 // Returns the Salesforce Instance that is currently being run on,
 // e.g. na12, cs5, etc.
public static String Instance {
    public get {
        if (Instance == null) {
            // Possible Scenarios:
            // (1) ion--test1--nexus.cs0.visual.force.com  --- 5 parts, Instance is 2nd part
            // (2) na12.salesforce.com      --- 3 parts, Instance is 1st part
            // (3) ion.my.salesforce.com    --- 4 parts, Instance is not determinable

            // Split up the hostname using the period as a delimiter
            List<String> parts = System.URL.getSalesforceBaseUrl().getHost().replace('-api','').split('\\.');
            if (parts.size() == 3) Instance = parts[0];
            else if (parts.size() == 5) Instance = parts[1];
            else Instance = null;
        } return Instance;
    } private set;

// And you can then get the Salesforce base URL like this:
public static String GetBaseUrlForInstance() {

     return 'https://' + Instance + '.salesforce.com';


FYI: For Scenario (1), the 5 1st of the 4-part hostname can get really 4 complicated, but you'll always be able to 3 find the Instance name as the 2nd part. For 2 those who are interested, the syntax of 1 Scenario 1 follows this pattern:

Score: 3

Here you have a quite nice and small snippet, that 2 does, what it should for VisualforcePages 1 :-)

        String sUrlRewrite = System.URL.getSalesforceBaseUrl().getHost();
        //  Example: c.cs7.visual.force.com
        sUrlRewrite = 'https://'
                + sUrlRewrite.substring(2,6) 
                + 'salesforce.com'
                + '/'
                + recordId;

// Returns: https://cs7.salesforce.com/00kM00000050jFMIAY

Score: 3

Use:    Url.getOrgDomainUrl().toExternalForm()

Thanks, Tim Lewis

Note behaviour changes between releases 3 and is sensitive to My Domain settings:

  • @Future context returns https://na1.salesforce.com
  • Visualforce context returns https://na1.salesforce.com
  • Force.com Site context returns https://na1.salesforce.com
  • @Future context returns https://mydomain.my.salesforce.com
  • Visualforce context returns https://mydomain.my.salesforce.com
  • Force.com Site context returns https://mydomain.my.salesforce.com

My Domain is 2 mandatory in new orgs effective Winter '21.
Enhanced Domains is 1 mandatory in all orgs effective Summer '22.

// Not to be confused with Url.getSalesforceBaseUrl()
// http://na1.salesforce.com (can happen in async apex)
// https://c.na1.visual.force.com (local Visualforce Page)
// https://ns.na1.visual.force.com (packaged Visualforce Page)
// https://custom.my.salesforce.com (org has My Domain enabled)
// https://sandbox-mydomain.na1.force.com (sandbox site with My Domain...)

See also the Salesforce Identity API which attests the pod/instance endpoint.

Score: 0

Fix to Alex_E snippet:

    String sUrlRewrite = System.URL.getSalesforceBaseUrl().getHost();
    String sfBaseProtocol = System.URL.getSalesforceBaseUrl().getProtocol();

    //remove namespace
    integer firstDotPos = sUrlRewrite.indexOf('.');
    sURlRewrite = sURlRewrite.substring(firstDotPos+1);

    //replace visual.force with salesforce
    sURlRewrite = sURlRewrite.replace('visual.force', 'salesforce');
    sUrlRewrite = sfBaseProtocol+'://'+sURlRewrite;

serverURL = sUrlRewrite;


Score: 0

This works for me:

String sUrlRewrite = System.URL.getSalesforceBaseUrl().getProtocol() 
    + '://' + System.URL.getSalesforceBaseUrl().getHost() 
    + '/' + record.Id;


Score: 0

Here is something to do with regex

public String getURL() {
    return String.format(
      new String[]{


More Related questions