home_url( string $path = '', string|null $scheme = null ): string
- Since
- 3.0.0
- Source
wp-includes/link-template.php:3441
Builds a front-end URL for the current site using the 'home' option, optionally appending a path and forcing a scheme. It automatically switches to https when is_ssl() is true, unless you pass 'http' or 'https' explicitly to override that check. Use esc_url() when echoing the result inside HTML to avoid unescaped output.
Description
Returns the 'home' option with the appropriate protocol. The protocol will be 'https' if is_ssl() evaluates to true; otherwise, it will be the same as the 'home' option.
If $scheme is 'http' or 'https', is_ssl() is overridden.
Compatibility
- WordPress
- since 3.0.0
- PHP
- 7.4–8.6-dev
- 6.7.7
- 6.8.8
- 6.9.7
- 7.0.4
- 7.1.0
Present in every tracked release (6.7.7 to 7.1.0), and compiles on PHP 7.4 through 8.6-dev.
Parameters
$pathstringoptional- Path relative to the home URL. Default empty.Default:
'' $schemestring|nulloptional- Scheme to give the home URL context. Accepts 'http', 'https', 'relative', 'rest', or null. Default null.Default:
null
Return value
string- Home URL link with optional path appended.
Code examples
Every example is editable and runs in a real WordPress booted in your browser by WordPress Playground. Press Run, then edit the code: clicking away re-runs it. Nothing is sent anywhere until you do.
Print a link back to the homepage with a path appended
A theme template wants to build a 'Back to shop' link relative to the site's home URL.
$shop_link = home_url( '/shop/' );
echo esc_html( $shop_link );home_url() concatenates $path onto the home option as-is, so include the leading slash yourself.
See how the scheme argument changes the returned URL
Compare what home_url() returns for each accepted $scheme value against the same path.
$schemes = array( 'http', 'https', 'relative', 'rest', null );
foreach ( $schemes as $scheme ) {
$label = null === $scheme ? 'null (default)' : $scheme;
printf(
'%s => %s<br>',
esc_html( $label ),
esc_html( home_url( '/sample-page/', $scheme ) )
);
}Passing 'http' or 'https' overrides whatever is_ssl() would otherwise decide.
Common problems and fixes · 4
- Why does home_url() return a different domain than I expected?
- Why is my URL http:// even though the page is loaded over https?
- Do I need to escape the output of home_url()?
- What's the difference between home_url() and site_url()?
Why does home_url() return a different domain than I expected?
Why is my URL http:// even though the page is loaded over https?
Do I need to escape the output of home_url()?
What's the difference between home_url() and site_url()?
Alternatives and related functions
get_home_url- When you need a URL for a specific site on a multisite network rather than the current one, since home_url() always passes null as the blog ID.
site_url- When the URL needs to point at WordPress core files (login, admin-ajax.php) rather than the front end visitors see.
admin_url- When building a link into wp-admin, since that appends the /wp-admin/ path onto the site URL for you.
content_url- When linking to a file inside wp-content rather than to a front-end page or post.
Performance profile
How much work a call to home_url() does, and what it touches: the algorithmic scaling, the Zend instruction count per call across PHP versions, the hooks it hands control to, and the core code that calls it. Measured from the compiled opcodes, not a stopwatch, so every number is identical on any machine running the same PHP version, and every function in core is ranked by cost.
- Cost class
- Moderate
- Scaling
- Constant
- Instructions
- 8
- Plugin surface
- None
- Called by
- 50
Reads stored settings via get_option(), cached per request but not free on a cold cache.
No loop in the body: the same number of instructions runs whatever you pass in.
Executed per call on PHP 8.5. The body compiles to 8.
Nothing here hands control to plugin code.
50 places in core call this, so the cost is paid more often than your own code shows.
What it touches
- optionoption read or write
get_option()one call below home_url() - hookthird-party callbacks
apply_filters()one call below home_url()
Further down the call graph this can also reach cache, serialize, query and transient. Those are the worst case, several calls deep and usually down an error path, not what a normal call pays.
What one call costs · 1 distinct outcome
One number would be a lie: the work depends on which branch runs. These are every distinct cost home_url() can have, taken from its control-flow graph on PHP 8.5.
| When | Instructions | Calls it makes |
|---|---|---|
| always | 8 | get_home_url() |
Across PHP versions
Compiles the same on PHP 7.4, 8.1, 8.2, 8.3, 8.4, 8.5 and 8.6-dev: 8 instructions, 8 executed per call, 0 branches. The work does not change between versions.
An instruction is not a fixed amount of time, so a matching count is not necessarily the same speed; what it rules out is a difference in the work itself.
Uses · 1
- get_home_url()Retrieves the URL for a given site where the front end is accessible.
Used by · 50
- Custom_Background::admin_page()Displays the custom background page.
- Custom_Image_Header::step_1()Displays first step of custom header image page.
- WP::parse_request()Parses the request to find the correct WordPress query.
- WP_Admin_Bar::initialize()Initializes the admin bar.
- WP_Automatic_Updater::has_fatal_error()Performs a loopback request to check for potential fatal errors.
- WP_Automatic_Updater::send_debug_email()Prepares and sends an email of a full log of background update results, useful for debugging and geekery.
- WP_Automatic_Updater::send_email()Sends an email upon the completion or failure of a background core update.
- WP_Automatic_Updater::send_plugin_theme_email()Sends an email upon the completion or failure of a plugin or theme background update.
- WP_Community_Events::get_events()Gets data about events near a particular location.
- WP_Customize_Manager::customize_pane_settings()Prints JavaScript settings for parent window.
- WP_Customize_Manager::customize_preview_settings()Prints JavaScript settings for preview frame.
- WP_Customize_Manager::get_allowed_urls()Gets URLs allowed to be previewed.
Show all 50
- WP_Customize_Manager::get_preview_url()Gets the initial URL to be previewed.
- WP_Customize_Manager::get_return_url()Gets URL to link the user to when closing the Customizer.
- WP_Customize_Manager::is_cross_domain()Determines whether the admin and the frontend are on different domains.
- WP_Customize_Manager::set_preview_url()Sets the initial URL to be previewed.
- WP_Customize_Nav_Menus::load_available_items_query()Performs the post_type and taxonomy queries for loading available menu items.
- WP_Customize_Nav_Menus::search_available_items_query()Performs post queries for available-item searching.
- WP_REST_Server::get_index()Retrieves the site index.
- WP_Recovery_Mode::handle_exit_recovery_mode()Handles a request to exit Recovery Mode.
- WP_Recovery_Mode_Email_Service::send_recovery_mode_email()Sends the Recovery Mode email to the site admin email address.
- WP_Rewrite::iis7_url_rewrite_rules()Retrieves IIS7 URL Rewrite formatted rewrite rules to write to web.config file.
- WP_Rewrite::mod_rewrite_rules()Retrieves mod_rewrite-formatted rewrite rules to write to .htaccess.
- WP_Rewrite::rewrite_rules()Constructs rewrite matches and queries from permalink structure.
- WP_Site_Health::check_for_page_caching()Checks if site has page cache enabled or not.
- WP_Sitemaps_Index::get_index_url()Builds the URL for the sitemap index.
- WP_Sitemaps_Posts::get_url_list()Gets a URL list for a post type sitemap.
- WP_Sitemaps_Provider::get_sitemap_url()Gets the URL of a sitemap entry.
- WP_Sitemaps_Renderer::get_sitemap_index_stylesheet_url()Gets the URL for the sitemap index stylesheet.
- WP_Sitemaps_Renderer::get_sitemap_stylesheet_url()Gets the URL for the sitemap stylesheet.
- WP_URL_Pattern_Prefixer::get_default_contexts()Returns the default contexts used by the class.
- WP_Widget_Categories::widget()Outputs the content for the current Categories widget instance.
- WP_Widget_RSS::widget()Outputs the content for the current RSS widget instance.
- WP_oEmbed::__construct()Constructor.
- _get_page_link()Retrieves the page permalink.
- _wp_customize_loader_settings()Adds settings for the customize-loader script.
- _wp_menu_item_classes_by_context()Adds the class property classes for the current context, if applicable.
- _wp_privacy_send_erasure_fulfillment_notification()Notifies the user when their erasure request is fulfilled.
- _wp_privacy_send_request_confirmation_notification()Notifies the site administrator via email when a request is confirmed.
- admin_created_user_email()
- block_core_archives_build_dropdown_script()Generates the inline script for an archives dropdown field.
- build_dropdown_script_block_core_categories()Generates the inline script for a categories dropdown field.
- confirm_another_blog_signup()Shows a message confirming that the new site has been created.
- get_allowed_http_origins()Retrieves list of allowed HTTP origins.
- get_attachment_link()Retrieves the permalink for an attachment.
- get_author_feed_link()Retrieves the feed link for a given author.
- get_author_posts_url()Retrieves the URL to the author page for the user with the ID provided.
- get_bloginfo()Retrieves information about the current site.
- get_custom_logo()Returns a custom logo, linked to home unless the theme supports removing the link on the home page.
- get_day_link()Retrieves the permalink for the day archives with year and month.
Source code
function home_url( $path = '', $scheme = null ) { return get_home_url( null, $path, $scheme );}Changelog
Introduced in 3.0.0. Unchanged from 6.7.7 through 7.1.0.
Signature, return type and hooks compared across 5 parsed releases.
About this page
- Parsed data
- Generated from the wordpress-develop 7.0.4 tag, from
src/wp-includes/link-template.php, and regenerated for each WordPress release so it tracks the code rather than a snapshot of it. - Corrections
- Something wrong on this page? Report it and it gets fixed in the next regeneration.