Update March 2015

It’s been a while since we created this post and some people have reported a few issues etc. We have updated the code to fix a few bugs, make the breadcrumbs more versatile (support more pages/archives), comments explaining what the code is doing and some general tidying up.

We hope the updated code proves to be a simple, effective solution for your breadcrumb needs!

If you do have any issues or suggestions, feel free to leave us a comment.

– – – – – – – –

Breadcrumbs are a navigational technique displaying all visited pages leading from the home page to the currently viewed page. All pages are linked for easy backwards navigation. Typically this is placed near the top of a web page. So for example, if you look to the top of this page you will see the breadcrumb navigation menu that leads a path back to the homepage.

There are loads of WordPress plugins out there that can handle breadcrumbs for you, but they are not always the best option as they can often get things wrong and end up being more hassle than they are worth. The following code will have breadcrumbs working on your site in no time.

Simply paste the code below into your theme’s functions.php file:


function the_breadcrumb () {
	// Settings
	$separator	= '&gt;';
	$id 		= 'breadcrumbs';
	$class 		= 'breadcrumbs';
	$home_title = 'Homepage';
    // Get the query & post information
	global $post,$wp_query;
	$category = get_the_category();
	// Build the breadcrums
    echo '<ul id="' . $id . '" class="' . $class . '">';
	// Do not display on the homepage
    if ( !is_front_page() ) {
		// Home page
        echo '<li class="item-home"><a class="bread-link bread-home" href="' . get_home_url() . '" title="' . $home_title . '">' . $home_title . '</a></li>';
        echo '<li class="separator separator-home"> ' . $separator . ' </li>';
        if ( is_single() ) {
			// Single post (Only display the first category)
			echo '<li class="item-cat item-cat-' . $category[0]->term_id . ' item-cat-' . $category[0]->category_nicename . '"><a class="bread-cat bread-cat-' . $category[0]->term_id . ' bread-cat-' . $category[0]->category_nicename . '" href="' . get_category_link($category[0]->term_id ) . '" title="' . $category[0]->cat_name . '">' . $category[0]->cat_name . '</a></li>';
			echo '<li class="separator separator-' . $category[0]->term_id . '"> ' . $separator . ' </li>';
			echo '<li class="item-current item-' . $post->ID . '"><strong class="bread-current bread-' . $post->ID . '" title="' . get_the_title() . '">' . get_the_title() . '</strong></li>';
        } else if ( is_category() ) {
			// Category page
			echo '<li class="item-current item-cat-' . $category[0]->term_id . ' item-cat-' . $category[0]->category_nicename . '"><strong class="bread-current bread-cat-' . $category[0]->term_id . ' bread-cat-' . $category[0]->category_nicename . '">' . $category[0]->cat_name . '</strong></li>';
        } else if ( is_page() ) {
			// Standard page
            if( $post->post_parent ){
				// If child page, get parents 
                $anc = get_post_ancestors( $post->ID );
				// Get parents in the right order
				$anc = array_reverse($anc);
				// Parent page loop
                foreach ( $anc as $ancestor ) {
                    $parents .= '<li class="item-parent item-parent-' . $ancestor . '"><a class="bread-parent bread-parent-' . $ancestor . '" href="' . get_permalink($ancestor) . '" title="' . get_the_title($ancestor) . '">' . get_the_title($ancestor) . '</a></li>';
					$parents .= '<li class="separator separator-' . $ancestor . '"> ' . $separator . ' </li>';
				// Display parent pages
                echo $parents;
				// Current page
                echo '<li class="item-current item-' . $post->ID . '"><strong title="' . get_the_title() . '"> ' . get_the_title() . '</strong></li>';
            } else {
				// Just display current page if not parents
                echo '<li class="item-current item-' . $post->ID . '"><strong class="bread-current bread-' . $post->ID . '"> ' . get_the_title() . '</strong></li>';
        } else if ( is_tag() ) {
			// Tag page
			// Get tag information
			$term_id = get_query_var('tag_id');
			$taxonomy = 'post_tag';
			$args ='include=' . $term_id;
			$terms = get_terms( $taxonomy, $args );
			// Display the tag name
			echo '<li class="item-current item-tag-' . $terms[0]->term_id . ' item-tag-' . $terms[0]->slug . '"><strong class="bread-current bread-tag-' . $terms[0]->term_id . ' bread-tag-' . $terms[0]->slug . '">' . $terms[0]->name . '</strong></li>';
		} elseif ( is_day() ) {
			// Day archive
			// Year link
			echo '<li class="item-year item-year-' . get_the_time('Y') . '"><a class="bread-year bread-year-' . get_the_time('Y') . '" href="' . get_year_link( get_the_time('Y') ) . '" title="' . get_the_time('Y') . '">' . get_the_time('Y') . ' Archives</a></li>';
			echo '<li class="separator separator-' . get_the_time('Y') . '"> ' . $separator . ' </li>';
			// Month link
			echo '<li class="item-month item-month-' . get_the_time('m') . '"><a class="bread-month bread-month-' . get_the_time('m') . '" href="' . get_month_link( get_the_time('Y'), get_the_time('m') ) . '" title="' . get_the_time('M') . '">' . get_the_time('M') . ' Archives</a></li>';
			echo '<li class="separator separator-' . get_the_time('m') . '"> ' . $separator . ' </li>';
			// Day display
			echo '<li class="item-current item-' . get_the_time('j') . '"><strong class="bread-current bread-' . get_the_time('j') . '"> ' . get_the_time('jS') . ' ' . get_the_time('M') . ' Archives</strong></li>';
		} else if ( is_month() ) {
			// Month Archive
			// Year link
			echo '<li class="item-year item-year-' . get_the_time('Y') . '"><a class="bread-year bread-year-' . get_the_time('Y') . '" href="' . get_year_link( get_the_time('Y') ) . '" title="' . get_the_time('Y') . '">' . get_the_time('Y') . ' Archives</a></li>';
			echo '<li class="separator separator-' . get_the_time('Y') . '"> ' . $separator . ' </li>';
			// Month display
			echo '<li class="item-month item-month-' . get_the_time('m') . '"><strong class="bread-month bread-month-' . get_the_time('m') . '" title="' . get_the_time('M') . '">' . get_the_time('M') . ' Archives</strong></li>';
		} else if ( is_year() ) {
			// Display year archive
			echo '<li class="item-current item-current-' . get_the_time('Y') . '"><strong class="bread-current bread-current-' . get_the_time('Y') . '" title="' . get_the_time('Y') . '">' . get_the_time('Y') . ' Archives</strong></li>';
		} else if ( is_author() ) {
			// Auhor archive
			// Get the author information
			global $author;
            $userdata = get_userdata( $author );
			// Display author name
			echo '<li class="item-current item-current-' . $userdata->user_nicename . '"><strong class="bread-current bread-current-' . $userdata->user_nicename . '" title="' . $userdata->display_name . '">' . 'Author: ' . $userdata->display_name . '</strong></li>';
		} else if ( get_query_var('paged') ) {
			// Paginated archives
			echo '<li class="item-current item-current-' . get_query_var('paged') . '"><strong class="bread-current bread-current-' . get_query_var('paged') . '" title="Page ' . get_query_var('paged') . '">'.__('Page') . ' ' . get_query_var('paged') . '</strong></li>';
		} else if ( is_search() ) {
			// Search results page
			echo '<li class="item-current item-current-' . get_search_query() . '"><strong class="bread-current bread-current-' . get_search_query() . '" title="Search results for: ' . get_search_query() . '">Search results for: ' . get_search_query() . '</strong></li>';
		} elseif ( is_404() ) {
			// 404 page
			echo '<li>' . 'Error 404' . '</li>';
    echo '</ul>';


Then to call the breadcrumbs onto your page (usually in the header file), simply use the following code:

<?php the_breadcrumb(); ?>

Styling your breadcrumbs

Now the breadcrumbs need a bit of tidying up. Below is some basic CSS styles to get you going.

    margin:10px 0;
#breadcrumbs li{
#breadcrumbs .separator{

Related Terms:
Posted on 28th March 2013 by in Wordpress
  • Александр Роуссинов

    Thanks this worked beautifully.. Additionally I think you should add some default CSS markup to this page to make customization easier.. just a thought, since I’m doing the CSS styles right now.. hehe

  • Chris Fölschow

    Hey everyone! I just tried to implement this. Unfortunately this error comes up: Parse error: syntax error, unexpected ‘<' in /kunden/406516_25436/webseiten/wordpress/wp-content/themes/spun/functions.php on line 336

    But the real problem is that I cannot edit anything anymore. I can´t even log in to my admin site, all that comes up is this error. Please help me!!! I don´t know what to do.. :/
    Oh and if that helps: Its a wordpress blog

    • Guilherme Henrique

      Hey @chrisflschow:disqus I passed by same problem, you just need concaten the string into code;

      Like as showin':

      echo ” / “;

      instead choose one of the codes below:

      echo ‘ / ‘;
      echo ” / “;

      the character escapes the quotes

    • cazue


      Apologies for the error, double quotes were used instead of single!

      Hopefully you would have got your site back now, but in-case you haven’t. You need to log into your webserver via FTP and edit the functions.php file with a text editor such as Wordpad.

      I hope this helps.


  • carrathanatos

    This doesn’t have a use-case for pages with parent pages though. :/

    • Dan Miller

      check out my reply, I found how to fix it.

  • carrathanatos

    // Breadcrumbs function.

    function the_breadcrumbs($post) {

    echo ”;

    if (!is_home()) {

    echo ‘‘;

    echo ‘Home';

    echo “ > “;

    if (is_category() || is_single()) {

    echo ”;

    the_category(‘ > ‘);

    if (is_single()) {

    echo ” > “;


    echo ”;


    } elseif (is_page()) {

    $ancestors = get_post_ancestors($post);

    $ancestor_html = array();

    foreach ($ancestors as $ancestor) {

    $ancestor_html[] = “” . get_the_title($ancestor) . ““;


    echo implode(‘ > ‘, $ancestor_html);

    echo ‘ > ‘;

    echo the_title();

    echo ”;



    elseif (is_tag()) {single_tag_title();}

    elseif (is_day()) {echo”Archive for “; the_time(‘F jS, Y’); echo”;}

    elseif (is_month()) {echo”Archive for “; the_time(‘F, Y’); echo”;}

    elseif (is_year()) {echo”Archive for “; the_time(‘Y’); echo”;}

    elseif (is_author()) {echo”Author Archive”; echo”;}

    elseif (isset($_GET[‘paged’]) && !empty($_GET[‘paged’])) {echo “Blog Archives”; echo”;}

    elseif (is_search()) {echo”Search Results”; echo”;}

    echo ”;


    // End Breadcrumbs function.

    This takes care of pages with ancestors. Something similar to my pages implementation could probably also be used for posts? :)

    • cazue

      Hi Carrathanatos,

      Thanks for the suggestion. We actually just implemented something similar to a site we have been working on and have updated the code in this post accordingly.

      Your feedback is greatly appreciated.


  • Anat

    Works great exept for parent pages.
    Would it be possible to add this part to the function?

  • Dennis Wagner

    Thanks a lot.

    I only have one question: How do I get “Home” on homepage?


    • cazue

      Hi Dennis,

      To get “Home” on the homepage you need to add the following just before this line: echo ”;

      elseif (is_home()) { echo ‘Home‘; }

      I hope this helps

      • Dennis Wagner

        Hi Stuart,
        thanks for the quick reply.

        As I said, your code is great.

        But I already found a code that fits all my needs:

        Anyway, thank you for you help.


      • Comedy Quotes

        Where exactly does this code go? Cheers!!!

  • imaginemonkey


    Awesome code, thanks so much. Just one question, it seems like these links only go as deep as the pages you’re in, but when I’m in an actual post, I don’t see the breadcrumbs any more, nor do I see links to that post.

    It would go as far as: “page > category” but not the post itself. What code would I need to add for this to work?


    Edit: Nevermind, figured it out! Just had to call the function in my content-single.php file.


  • Adey Jones

    Hi, I see your comment saying you have updated your code accordingly to deal with ancestors, but I have created a page called application forms, and this parent has 2 child pages. Using your code, the breadcrumbs only display as “Home / Subpage1″ and misses out the parent. Has anyone else figured this out please? I could really do with a solution. Thanks

    • Dan Miller

      Yes, check out my reply

  • Böda

    It’s a pitty It doesn’t show the structure of pages and subpages.
    I have got this:
    Home / page3
    instead of this:
    Home / parentpage / page3

    • Dan Miller

      check out my reply, I found how to fix it. hope you see this

      • Ben Zitney

        I’m still having this problem

        • Ben Zitney


  • Bob Rock

    You need to put global $post; after function starts :/

  • wmike1503

    Thanks for this. Quick question – how can I display breadcrumbs with next and previous pages (using their post titles)?



  • Simon d

    Just add this at the top of the function and it works for child pages at the tertiary level
    global $post;
    $title = get_the_title();
    Thanks for the function Stuart! saved me many minutes 😉

  • Donald Aribam

    This is by far the best approach to Breadcrumbs in WordPress, Period!
    I have always wanted to contain the individual elements of the Breadcrumbs as List Items inside of an Unordered List.
    have searched for help Everywhere! Thank you Stuart, for I can now move
    on ahead with the rest of the design and not be Trapped in this one
    hell of a Fairy Tale!

  • Jamie Davidson

    Hi, I’ve added the code and it works perfectly. However when trying to add the parent > child > another child > navigation it breaks my site. Anyone got the actual code so the full breadcrumb trail shows? thanks,

  • Ian Jamieson

    I haven’t tested this, but line 30 you have:

    echo the_title();

    I would expect that this should be:

    echo get_the_title();

    Also, I got rid of all instances of and used the following as my CSS:

    ul#breacrumbs {
    ul#breacrumbs li {
    ul#breacrumbs li a:after {
    content: “|”;
    /* This could also be
    content:”/”; */
    padding: 0 2px;

    :after pseudo class does not work in IE7 and below.

  • Nikia

    Worked great – thank you!

  • Dan Miller

    Fixed the error when the page has multiple ancestors.
    ERROR: Home / Parent3 / Page
    FIXED: Home / Parent3 / Parent2 / Parent1 / Page
    And here is how you fix it:
    In this code you will find only one foreach() {} change it to this:

    foreach ( $anc as $ancestor ) {
    $output = $output . ‘‘.get_the_title($ancestor).’ /';

    The problem is that $output was overwritten each time there was an ancestor. By doing $output = $output . ‘content'; you are not overwriting the ancestor, but you are adding it.

  • Ed Swinfen

    This is a great little function which I’ve just used on a client’s site. However there is a slight problem with the logic, none of the outer elseif statements will ever get executed as is_home() will return false for the search results page, an archive page and the other cases so it will always go into the the top if block.

    This can be fixed by checking to see if we are dealing with a post/page or something else by changing line 5 to:

    if (is_singular() && !is_home()) {

  • Oliver Sands

    Function works great but HTML validation fails because the Strong element is not allowed as child of ul

  • Oliver Sands

    I removed the element and modified my css by targeting the UL element’s last child like this:

    .breadcrumb-navigation:last-child {
    font-weight: 900;

    That seemed to work. However, validation still fails because text is not allowed inside UL elements. Hopefully, I will find a quick solution without modifying the function.

    • Sam Sharples

      just put around the strong, it will be valid. You can have a strong tag within the li, it’s just all direct children of the ul tag need to be an li

  • http://dextered.com Dexter Lesaca

    How do we make it work with custom post types? Or did I miss something in the comments?

  • Sam Sharples

    Ok I figured out a fix for the pages with grandchildren
    I also had to reverse the order of my breadcrumbs which you might not have to do in which case you just need to put a full stop in this line

    $output .= ‘‘.get_the_title($ancestor).’ /';

    for the full fix replace the relevant part with:


    $anc = get_post_ancestors( $post->ID );

    $ancreverse = array_reverse($anc);

    $title = get_the_title();

    foreach ( $ancreverse as $ancestor ) {

    $output .= ‘‘.get_the_title($ancestor).’ /';


    echo $output;

    echo ‘ ‘.$title.’‘;


  • Kamal Dk

    Catchable fatal error: Object of class WP_Error could not be converted to string in

    this error shows, when i open image on media.
    i think the problem is here

    elseif ( is_single() ) {
    $cat = get_the_category(); $cat = $cat[0];
    echo get_category_parents($cat, TRUE, ‘ ‘ . $delimiter . ‘ ‘);
    echo $currentBefore;
    echo $currentAfter;}
    its single page bt not “get the get_category_parents($cat, TRUE, ‘ ‘ . $delimiter . ‘ ‘);”

  • Ricardo Amorim

    if you want to disable breadcrumbs in case of a static page change the function is_home() to is_front_page(). this function is available since wp 2.1. According to codex : “Returns true when the site front page is being displayed, regardless of whether ‘Settings > Reading ->Front page displays’ is set to “Your latest posts” or “A static page”. “

  • travisk3

    Just want to say thank you to Stuart for posting this, and also to Dan Miller for the Parent/Child pages fix.

    I’ve modified the example to include Dan’s fix and use Boostrap 3’s breadcrumb structure.
    I’ve also replaced the text that reads Home, to use the icon “glyphicon-home” from Bootstrap.

    This might be of use to anyone that is integrating Bootstrap 3 into their WordPress theme stack.

  • Eliana Garzón

    Hi everybody!
    I have an issue with multiple categories: when I publish a post with two (or more) at same level, the breadcrumb shows both categories incorrectly, like father and son.
    Thanks for your help.

  • Elise Coste

    Thanks for the sharing ! that is useful !

    i changed the first condition (!is_home()) by (!is_front_page()), for the case where the site use a static front page (as my site).

    I used the fix for the pages arborescence, and moved the extra } at the end of the if (is_category() || is_single()) (which was closing the “home” condition) at the bottom of the function

    also used the blog name rather than ‘home’ for the root, and used the localized sentences of my parent theme (twentyfourteen) for the archives (my site is not in english :))

    finally, removed the and the to use a and a , and added a $separator variable to avoid repeting the same html code each time.

    If that may be of any help to anybody, there is my version of the the_breadcrumb() function

    function the_breadcrumb() {
    global $post;
    $separator=’ / ‘;
    echo ”;
    if (!is_front_page()) {
    echo ‘‘;
    bloginfo( ‘name’ );
    echo ‘
    if (is_category() || is_single()) {
    if (is_single()) {
    echo $separator;
    } elseif (is_page()) {
    $anc = get_post_ancestors( $post->ID );
    $title = get_the_title();
    foreach ( $anc as $ancestor ) {
    $output = ‘‘.get_the_title($ancestor).’‘.$separator.$output;
    echo $output;
    echo ‘ ‘.$title.’‘;
    } else {
    echo ‘ ‘.get_the_title().’‘;
    elseif (is_tag()) {single_tag_title();}
    elseif (is_day()) { printf( __( ‘Daily Archives: %s’, ‘twentyfourteen’ ), get_the_date() ); }
    elseif (is_month()) { printf( __( ‘Monthly Archives: %s’, ‘twentyfourteen’ ), get_the_date( _x( ‘F Y’, ‘monthly archives date format’, ‘twentyfourteen’ ) ) ); }
    elseif (is_year()) { printf( __( ‘Yearly Archives: %s’, ‘twentyfourteen’ ), get_the_date( _x( ‘Y’, ‘yearly archives date format’, ‘twentyfourteen’ ) ) );}
    elseif (is_author()) { printf( __( ‘All posts by %s’, ‘twentyfourteen’ ), get_the_author() ); }
    elseif (isset($_GET[‘paged’]) && !empty($_GET[‘paged’])) {_e( ‘Archives’, ‘twentyfourteen’ ); }
    elseif (is_search()) {printf( __( ‘Search Results for: %s’, ‘twentyfourteen’ ), get_search_query() );}
    echo ”;

  • Scyzor

    I have tried to use solution above to resolve my issue with a “menu” based on a breadcrumb next/previous functionality described here http://wordpress.stackexchange.com/questions/144443/breadcrumb-a-like-single-navigation but so far I’m not able to navigate between top/parent menus.

    Any clue?


  • http://www.patchworkoftips.com/ Udegbunam Chukwudi

    Please how to I remove the post title from the breadcrumb?

  • http://www.nickelanddime.nl/ Nickel and Dime

    Thanks for the great simple solution!

  • http://www.bnewton.co.uk Ben Newton

    Hey – great little bit of code. Thanks for sharing. My only suggestion is to edit line #27. It’s currently missing ‘s which upsets the which they are nested within. Apart from that it works a treat, so thanks very much! – Ben

  • allenlimelbourne

    Hi, thanks for your code. I think there are two points can be updated.

    1. in line 21, the ancestors array could be reversed, because we’d like to display the grandparents first.
    $anc = array_reverse(get_post_ancestors( $post->ID ));

    2. in line 24, it could be $output .=

  • http://reuelteodoro.com Reuel Teodoro

    Hi can you re write this post as it’s no longer formatted correctly.

    • http://thewebtaylor.com/ The Web Taylor

      Hi, the post has been rewritten. Hopefully you will find it useful!


  • http://sensiweb.fr Jess

    Thank you very much ! Very useful :)

  • Alex Noble

    Got some weird problem where some catagories don’t display their names in the breadcrumbs….

    • Tom Kay

      I’ve got this exact same problem Alex, did you manage to find a solution?

      • Alex Noble

        I think its something to do with if a post belongs in more than one category if this helps at all??

      • Tom Kay

        Ah I got it, it was because the category did not have any posts in it

  • J Munce

    People, if you’re already in php on your functions.php file (good chance) you don’t need the opening and closing lines.

    How can I make this display intermediate breadcrumbs though?

    As is, it reads Homepage > (skips a category) 2nd level category > (skips a category) current page. I need to display ALL the breadcrumb trail of categories. Also, I want instead of “homepage” to read the title of the website and I don’t want to display the current page.


  • J Munce

    This didn’t do it for me. I tried replacing it but no change, unless I’m missing something. How did you do ‘echo’ on this?

  • J Munce

    I tried this solution, but it did not resolve it.

    How exactly did you implement this? Thanks

  • Lars E.rnst

    Hi, just wanted to let you know that i added this function to the great open source project FoundationPress. Cheers

  • ঝাক্কি বাবা

    amazing………its awesome,but it’s not rendering custom post name.I think it would be better use get_post_type_object( get_post_type($post) ); in a condition before grabing post type name. btw a lot of thanks for this nice code.

Web Agency Portsmouth
where to go from here? get in touch OR

give us a call on 02392 123 538

Let's be friends! More...
Facebook Twitter Google+
Like & Follow Facebook Twitter Google+
Share the love, share this page! Facebook Twitter Google Digg Reddit LinkedIn Pinterest Email
Close [X]
Web Design South Coast
Areas We Cover

Here are some of the local areas we provide with web design and digital marketing services. These are just some examples, we work with clients all over the UK and across the globe.

Our Services
Close [X]
The Web Taylor
Harcourt Close Waterlooville, Hampshire PO8 8JL
02392 123358