What’s the difference between home_url() and site_url()

My understanding is that site_url() returns the location where the WordPress core files are.

If my blog is hosted at http://example.com/blog then site_url() returns http://example.com/blog

But then how does home_url() differ? For me, home_url() returns the same thing: http://example.com/blog

If that’s correct, then can I get WordPress to return http://example.com/ ?

You are asking two questions at once:

  1. What’s the difference between home_url() and site_url()?
  2. How do I get WordPress to return the URL root without the subdirectory where it’s installed?

Here are the answers, and I confirmed with Andrew Nacin, a core developer of WordPress, as well as ran some server tests to confirm what Andrew told me.

Question # 1

In General > Settings of wp-admin, home_url() references the field labeled “Site Address (URL)”. Confusing, huh? Yeah, it says “Site Address” so you might assume site_url(), but you’d be wrong. Run your own test and you’ll see. (You can temporarily drop an echo H1 field with site_url() and home_url() values at the top of your your theme’s functions.php.)

Meanwhile, site_url() references the field labeled “WordPress Address (URL)” in General > Settings.

So, if you’re wanting to reference where a physical path might be such as calling a plugin’s folder path on the URL to load an image, or calling a theme’s folder path to load an image, you should actually use other functions for those – look at plugins_url() and get_template_directory_uri().

The site_url() will always be the location where you can reach the site by tacking on /wp-admin on the end, while home_url() would not reliably be this location.

The home_url() would be where you have set your homepage by setting General > Settings “Site Address (URL)” field.

Question # 2

So, if I have placed my blog in http://example.com/blog, and example.com is just some static site where I have like a portfolio theme, then this would be a scenario that lines up with your question. In such a case, then I would use this snippet of code:

<?php
function getDomain() {
    $sURL    = site_url(); // WordPress function
    $asParts = parse_url( $sURL ); // PHP function

    if ( ! $asParts )
      wp_die( 'ERROR: Path corrupt for parsing.' ); // replace this with a better error result

    $sScheme = $asParts['scheme'];
    $nPort   = $asParts['port'];
    $sHost   = $asParts['host'];
    $nPort   = 80 == $nPort ? '' : $nPort;
    $nPort="https" == $sScheme AND 443 == $nPort ? '' : $nPort;
    $sPort   = ! empty( $sPort ) ? ":$nPort" : '';
    $sReturn = $sScheme . '://' . $sHost . $sPort;

    return $sReturn;
}

Leave a Comment