90

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/ ?

2
  • 5
    You're asking two questions at once on a very important question. The answer to "What's the difference between home_url() and site_url()?" is different than the question, "How do I get WordPress to return the URL root without the subdirectory where it's installed?"
    – Volomike
    Apr 29, 2012 at 23:33
  • Review these codex guides: codex.wordpress.org/… ; codex.wordpress.org/… ; codex.wordpress.org/…
    – Tara
    Oct 7, 2016 at 2:44

7 Answers 7

74

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( $nPort ) ? ":$nPort" : '';
    $sReturn = $sScheme . '://' . $sHost . $sPort;

    return $sReturn;
}
6
  • Do you have a link to the discussion with A.Nacin?
    – kaiser
    Apr 30, 2012 at 1:02
  • 1
    It was via email. Sorry. Oh, and thanks for the edit -- I'll remember that syntax change next time.
    – Volomike
    Apr 30, 2012 at 2:07
  • 12
    It took me a very long time and a lot of pain to realize that 'Site Address (URL)' = 'home' and 'WordPress Address (URL)' = 'siteurl'. They should definitely change those labels.
    – Jbm
    Jan 26, 2014 at 3:33
  • Your answer to the second question hits the jackpot!
    – Devner
    Feb 19, 2018 at 8:08
  • It seems there is a typo in $sPort = ! empty( $sPort ) ? ":$nPort" : '';. I think ! empty( $sPort ) should be ! empty( $nPort ). Otherwise, ":$nPort" will never be reached, hence $sPort = '' and a port will never be appended to the third last line.
    – Ferris
    May 25 at 21:30
32

##TLDR:
In a non-standard installation, you can place your WordPress files in a subdirectory of your website root.
...and still allow your visitors to visitors to access your WordPress "website" from your site's Domain (root) URL, without appending the subdirectory name:
(ie: www.example.com vs www.example.com/wordpress):

WP function  | wp_options. | WP constant  | what it represents       | WP Settings Label | Example     
-------------------------------------------------------------------------------------------------------------------------------------
`site_url()` | `siteurl`   | `WP_SITEURL` | WordPress files location | WordPress Address | https://www.example.com/wordpress
`home_url()` | `home`      | `WP_HOME`    | browser address bar      | Site Address      | https://www.example.com 

Where the value for a WP constant takes precedence over an wp_options/ WP Settings value.

##Different Configurations for WordPress

In the most standard WordPress installations, home_url and site_url will have the same value.
Regardless, they represent two different things.

In a non-standard installation, they may have different values.

NOTE: I am leaving off the protocol in my answer for easier readability.
In this post, PREPEND EVERY URL with: https://, http:// OR //
(unless I included it already).

(// is the relative protocol and will work for either/both http:// or https://)

Standard Installations (including "One-Click" Installs)

home_url: is the home page of your (wordpress) website, as indicated in the user's address bar.
site_url: is the directory where your wordpress files are located.

WordPress's 5-minute install installs wordpress files these two values will be the same - wordpress files will be installed in the same folder that you want people to use to address your website, or the wordpress (blog) portion of your server's website.

Example 1:
user accesses your blog at: www.example.com,
wordpress files installed at: www.example.com, or the root folder of your server's website.

home_url === site_url === "www.example.com"

Example 2:
user accesses your blog at: www.example.com/blog,
wordpress files installed at: www.example.com/blog, or in the blog folder inside the root of your website.

home_url === site_url === "www.example.com/blog"

In this case www.example.com is the main website, and www.example.com/blog is the root of your blog.
Here your blog is separated from, and works as subset of, your main website.
In this case, your main website is not controlled, defined, or styled by WordPress.
Just your blog is. All urls in your blog will be proceeded by www.example.com/blog

Note: In documentation, "Wordpress site/website" (as opposed to simply "site/website") refers to the directory where your WordPress files are installed. In this case, it is www.example.com/blog - everything within the blog folder. The "WordPress website", in this scenario, is not the same as your domain, your root, or your main website. It is a subset of your overall website. Kind of like a website inside a website. I mention this as the terminology can seem unclear or confusing, given this particular setup.

Alternate WordPress Installation Configuration

Giving WordPress Its Own Directory, the section Method II (With URL change).

For example, many people don't want to clog up the root folder of their website with all the wordpress files.
They want to install wordpress in a subdirectory, *but have the "blog" or "WordPress website" accessed as if the files were installed in the root of the server's root for the website.

This is particularly be true when WordPress is used to build and run an entire website that does not even have a "blog".

Example 3:
user accesses your "blog" at: www.example.com,
wordpress files installed at: www.example.com/wordpress, or the root folder of your server's website.

home_url === "www.example.com"
site_url === "www.example.com/wordpress"

(Note: this configuration will not work "out of the box" just by changing the values of these variables. It requires additional configuration changes to work properly)
See Giving WordPress Its Own Directory, the section titled Method II (With URL change) for how to do this.

In this case home_url and site_url should hold different values.

In this setup, you want your website to function exactly as if WordPress files were installed in the server's root directory for your website...
BUT, for organizational purposes on the server,
you actually have your WordPress files in a folder called wordpress in the server's root directory for your website.

So, user will type in www.example.com to get your WordPress home page, instead of www.example.com/wordpress

wordpress function <--> database variable <--> Wordpress Constant

This section assumes Example 3 configuration above.
address bar url: www.example.com
wordpress files: /wordpress directory

(The other cases are trivial: All variables/functions hold/return the same value.)

How to set the values for site_url and home_url

First, let me note that siteurl and home store values returned by the functions above

  1. Normally you set these values on the WordPress backend/dashboard/admin panel:
    Settings -> General ->
    siteurl WordPress Address: https://www.example.com/wordpress
    home Site Address: https://www.example.com

(do not include trailing slashes here - that would be configured elsewhere)

  1. Alternatively, you set these values in your WordPress database:
    wp_options table ->

    options_name | options_value

    siteurl | https://www.example.com/wordpress
    home | https://www.example.com

(do not include trailing slashes here - that would be configured elsewhere)

  1. Edit your wp-config.php
    Define these specific constants to hold your values
    Define WP_HOME and WP_SITEURL settings by inserting these lines toward the top of your wp-config.php file:

    define('WP_SITEURL','http://example.com/wordpress'); // wordpress core files define('WP_HOME','http://example.com'); // address bar url

    // ** MySQL settings - You can get this info from your web host ** // ...
    (do not include trailing slashes here - that would be configured elsewhere)

Reference: WP_SITEURL and WP_HOME

NOTE: This is confusing
(I really wish WordPress had Labeled the Settings similar to their php names,
such as Wordpress Site Address and Home Page Address or something more explicit like location of WordPress Site core files and browser url to access WordPress home page)

`WP_SITEURL` <--> `site_url()` <--> `siteurl` <--> Wordpress Address <--> /wordpress   
`WP_HOME`    <--> `home_url()` <--> `home`    <--> Site Address      <--> /

Now Here is where it gets tricky !

IF you defined those constants in your wp-config.php file, it does not matter what values you have in your database/settings page.
In fact, you will not be able to modify this value through the back end (it'll be greyed out). You can still modify in by editing your database, but doing so will have no effect on your site, while the constants exist in your wp-config file.

You config file will not change the values in your database (or hence you settings page). Instead, your database/settings page values will be ignored. The values in wp-config override or take precedence over your database setting.

#So... to wrap up (TLDR) :

WP function  | wp_options. | WP constant  | what it represents       | WP Settings Label | Example     
-------------------------------------------------------------------------------------------------------------------------------------
`site_url()` | `siteurl`   | `WP_SITEURL` | WordPress files location | WordPress Address | https://www.example.com/wordpress
`home_url()` | `home`      | `WP_HOME`    | browser address bar      | Site Address      | https://www.example.com 

Where the value for a WP constant takes precedence over an wp_options/ WP Settings value.

The wp_options record value and the WP Settings value are the same.
Editing one, by definition edits the other.
It is just 2 different ways of accessing the same variable.

On the other hand, the WordPress Constants are unique and independent.
Internally, WordPress (PHP) constants override their db counterparts.
If a constant is defined in wp-config, it does not change the database.
But internally WordPress will always prefer/use its value instead of the db one.

9

If you want WP installed in a directory but the site home on your domain root, you need to move the main index.php file out to your domain root and edit the require statement to point within your directory.

This process is outlined here: Giving WordPress Its Own Directory.

5
  • I always just use home_url() since i am on wp network mode. I have only given WordPress its own directory once and it just was not my liking. But i do however use the wp_content_dir on some sites. Jun 17, 2011 at 18:29
  • I don't have any experience with multisite, so I'm not familiar how this stuff works in that situation. I prefer installing WP in a directory just to keep things clean and not clutter the root.
    – Milo
    Jun 17, 2011 at 18:34
  • my file structure is probably one of the neatest ones around. home/usr/public_html/site1 home/usr/public_html/site2 and so on and then the wp_content_dir is usually on a cdn Jun 17, 2011 at 18:39
  • if a WP install were the only thing there it would be fine, but I'm mostly working on other peoples servers with hundreds of files and directories littered about.
    – Milo
    Jun 17, 2011 at 18:46
  • Is my understanding correct that site_url() and home_url() are the same, unless one sets up their wordpress install directory to be different than the root?
    – Praveen
    Jun 20, 2011 at 19:00
5

The site_url() and home_url() functions are similar and can lead to confusion in how they work.

The site_url() function retrieves the value value for siteurl in the wp_options table in your database.

This is the URL to the WordPress core files.
If your core files exist in a subdirectory /wordpress on your web server, the value would be http://example.com/wordpress.

The home_url() function retrieves the value for home in the wp_options table in your database.

This is the address you want people to visit to view your WordPress web site.

If your WordPress core files exist in /wordpress, but you want your web site URL to be http://example.com the home value should be http://example.com.

2

To answer your second question:

Q: If that's correct, then can I get wordpress to return http://example.com/ ?

You can't, unless you take the Giving WordPress its own directory steps. Using this means you put WordPress core files into /blog or /WordPress and then the index.php into your root.

If you decide to put WordPress inside its own directory then you would use home_url() for going to index.php and site_url() for getting core files and such.

Refrences:
Codex for site_url
Codex for home_url
Codex for Giving Wordpress Own Directory

0
0

Your first question it is responsed, but i think the easiest way to retrieve your root domain is with the function bloginfo('url'); also, bloginfo() have some others parameters to return , check the documentation.

There's a get_bloginfo() too to check if you want to wrap the content into a var.

1
  • While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. - From Review
    – cjbj
    Oct 14 at 9:45
-1

The easiest way to get the site url without any sub-directories ( http://example.com/ instead of http://example.com/blog ), just use the backslash /

For example, if you type:

<a href="/">domain url</a>

It will create a link that goes to your domain

1
  • Thanks for participating. Unfortunately, this does not answer the question posed by the OP. There are many reasons why a person needs to use the wordpress functions OP asks about. It is unlikely that OP simply wants to add link to their home page via html, such as by editing a post. It is more likely, OP is editing a php theme file, or a plugin file. In any case, they are working with php, not html. Finally, while OP expected a value without / for this site, on a different site, OP may expect a subdirectory to be returned. It depends on the WP configuration for each site. Jan 5, 2019 at 2:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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