Displays or retrieves page title for all areas of blog.
Description
By default, the page title will display the separator before the page title, so that the blog title will be before the page title. This is not good for title display, since the blog title shows up on most tabs and not what is important, which is the page that the user is looking at.
There are also SEO benefits to having the blog title after or to the ‘right’ of the page title. However, it is mostly common sense to have the blog title to the right with most browsers supporting tabs. You can achieve this by using the seplocation parameter and setting the value to ‘right’. This change was introduced around 2.5.0, in case backward compatibility of themes is important.
Parameters
$sepstringoptional- How to separate the various items within the page title.
Default'»'.Default:
'»' $displaybooloptional- Whether to display or retrieve title.
Default:
true $seplocationstringoptional- Location of the separator (either
'left'or'right').Default:
''
Source
function wp_title( $sep = '»', $display = true, $seplocation = '' ) {
global $wp_locale;
$m = get_query_var( 'm' );
$year = get_query_var( 'year' );
$monthnum = get_query_var( 'monthnum' );
$day = get_query_var( 'day' );
$search = get_query_var( 's' );
$title = '';
$t_sep = '%WP_TITLE_SEP%'; // Temporary separator, for accurate flipping, if necessary.
// If there is a post.
if ( is_single() || ( is_home() && ! is_front_page() ) || ( is_page() && ! is_front_page() ) ) {
$title = single_post_title( '', false );
}
// If there's a post type archive.
if ( is_post_type_archive() ) {
$post_type = get_query_var( 'post_type' );
if ( is_array( $post_type ) ) {
$post_type = reset( $post_type );
}
$post_type_object = get_post_type_object( $post_type );
if ( ! $post_type_object->has_archive ) {
$title = post_type_archive_title( '', false );
}
}
// If there's a category or tag.
if ( is_category() || is_tag() ) {
$title = single_term_title( '', false );
}
// If there's a taxonomy.
if ( is_tax() ) {
$term = get_queried_object();
if ( $term ) {
$tax = get_taxonomy( $term->taxonomy );
$title = single_term_title( $tax->labels->name . $t_sep, false );
}
}
// If there's an author.
if ( is_author() && ! is_post_type_archive() ) {
$author = get_queried_object();
if ( $author ) {
$title = $author->display_name;
}
}
// Post type archives with has_archive should override terms.
if ( is_post_type_archive() && $post_type_object->has_archive ) {
$title = post_type_archive_title( '', false );
}
// If there's a month.
if ( is_archive() && ! empty( $m ) ) {
$my_year = substr( $m, 0, 4 );
$my_month = substr( $m, 4, 2 );
$my_day = (int) substr( $m, 6, 2 );
$title = $my_year .
( $my_month ? $t_sep . $wp_locale->get_month( $my_month ) : '' ) .
( $my_day ? $t_sep . $my_day : '' );
}
// If there's a year.
if ( is_archive() && ! empty( $year ) ) {
$title = $year;
if ( ! empty( $monthnum ) ) {
$title .= $t_sep . $wp_locale->get_month( $monthnum );
}
if ( ! empty( $day ) ) {
$title .= $t_sep . zeroise( $day, 2 );
}
}
// If it's a search.
if ( is_search() ) {
/* translators: 1: Separator, 2: Search query. */
$title = sprintf( __( 'Search Results %1$s %2$s' ), $t_sep, strip_tags( $search ) );
}
// If it's a 404 page.
if ( is_404() ) {
$title = __( 'Page not found' );
}
if ( ! is_string( $title ) ) {
$title = '';
}
$prefix = '';
$title_array = array();
if ( '' !== $title ) {
$prefix = " $sep ";
$title_array = explode( $t_sep, $title );
}
/**
* Filters the parts of the page title.
*
* @since 4.0.0
*
* @param string[] $title_array Array of parts of the page title.
*/
$title_array = apply_filters( 'wp_title_parts', $title_array );
// Determines position of the separator and direction of the breadcrumb.
if ( 'right' === $seplocation ) { // Separator on right, so reverse the order.
$title_array = array_reverse( $title_array );
$title = implode( " $sep ", $title_array ) . $prefix;
} else {
$title = $prefix . implode( " $sep ", $title_array );
}
/**
* Filters the text of the page title.
*
* @since 2.0.0
*
* @param string $title Page title.
* @param string $sep Title separator.
* @param string $seplocation Location of the separator (either 'left' or 'right').
*/
$title = apply_filters( 'wp_title', $title, $sep, $seplocation );
// Send it out.
if ( $display ) {
echo $title;
} else {
return $title;
}
}
Hooks
- apply_filters( ‘wp_title’,
string $title ,string $sep ,string $seplocation ) Filters the text of the page title.
- apply_filters( ‘wp_title_parts’,
string[] $title_array ) Filters the parts of the page title.
Changelog
| Version | Description |
|---|---|
| 1.0.0 | Introduced. |

Following is the recommended way instead of wp_title() function.
It should be placed in the functions.php file with
after_setup_themeaction hook.wp_title() was originally to be deprecated in 4.4, but was reinstated while efforts were made to identify the unintended ways in which the function was being used to ensure that the deprecation wouldn’t break them. With the likelihood that wp_title() will be deprecated in the near future, it is recommended that you instead use its replacement: the title-tag theme feature.
Zero-character sep
The sep string may be zero characters, which will remove » from the returned value. To do this, set the sep parameter to zero characters, for example:
If the title of the post is “Hello world!”, then the function will return:
Hello world!
Customizing with the filter
If you want to change the way that the title displays on different pages you can use a filter.
Covering Homepage
If you are using a custom homepage with custom loops and stuff or a custom front-page, you will have an empty
wp_title. Here goes a neat hack to add the description/tagline at thewp_titleplace on homepage:Then in your
functions.phpfile in your theme:You can format this string as you want of course.
Default
If you do not pass any parameters for a single post, for example:
If the title of the post is “Hello world!”, then the function will return
» Hello world!
Just wanted to check line 833 for mis-spelling:
$t_sep = ‘%WP_TITILE_SEP%’; // Temporary separator, for accurate flipping, if necessary
Is WP_TITILE_SEP spelled correctly? I might have thought it to be WP_TITLE_SEP
I noticed this in my WP php file, and then again here.
Display blog title after page/post title:
To solve the Homepage empty title tag I’m using this code below, on header.php template:
For setting POST_NAME | BLOG_NAME, this one line code should be great
To solve the Homepage empty title tag using this code on header.php :
But as 2025, this function left behind already. We use this in functions.php:
add_theme_support( ‘title-tag’ );