Breadcrumb trails show users their location on your website. If you’re not familiar, the term “breadcrumb” comes from the tale of Hansel and Gretel, where the main character left a trail of breadcrumbs to find the way back home…
And just like in fairy tales, users need to know their location in the hierarchical structure of the site to navigate to a higher level in the hierarchy.
In this article, I will elaborate on breadcrumbs on WordPress sites (and in general), demonstrate how to embed them, and explain the advantages of breadcrumbs in terms of Google SEO and user experience. These aspects go hand in hand…
Why to use Breadcrumbs
Breadcrumbs are a visual and efficient aid that indicates the user’s position in the site’s hierarchy. This information helps users answer the following questions:
- Where am I? Breadcrumbs show users their location in relation to the overall hierarchy of the site they are in.
- Where can I go? Breadcrumbs enhance user navigation in different parts of your site and its pages. The site structure is clearer when using breadcrumbs compared to attempting to understand it from the main menu structure.
- Should I navigate there? Breadcrumbs encourage site navigation and help users find the most relevant content. In e-commerce sites and online stores, for example, a visitor landing on a page for a specific product that doesn’t precisely match what they are looking for can, with a click, go to the category of that product and search for a more suitable item. This action naturally reduces the bounce rate of the site.
What Else Can Be Said About Breadcrumbs?
- Reduce the number of actions – In terms of usability and user experience, breadcrumbs reduce the number of actions a visitor needs to take to reach a higher level in the site hierarchy. Instead of using the browser’s back button or the main menu to reach a higher level, users can use breadcrumbs.
- Require minimal space – The compact mechanism takes up little space on the page as it is just text with horizontal links. The advantage is that it doesn’t negatively impact the content load, and the visual impact is minimal.
- No user dislikes breadcrumbs – Users may overlook the breadcrumb element, but they will never reach a point where they don’t understand what it is and naturally know how to operate or use it.
- Google loves them, and they aid in site promotion – You can read more about this at the end of the article…
When to Use Breadcrumbs?
One way to understand if your WordPress site will benefit from breadcrumbs is to create a visual sitemap or diagram representing the navigation structure and then analyze whether breadcrumbs will improve the user’s comfort navigating between categories on your WordPress site:
- Note that you should use breadcrumbs when your site has a large amount of content organized in a linear structure or when you have a hierarchical structure with defined categories. An excellent example is e-commerce sites with a large quantity of products grouped into categories.
- Do not use breadcrumbs on single-level websites where there is no logical hierarchy.
While not elaborating, it’s essential to mention that there are 3 types of breadcrumbs: location-based, attribute-based, and path-based. You can read more about the differences in this article.
Optimal Use of Breadcrumbs
When designing breadcrumbs, pay attention to the following aspects to maintain the effectiveness of this element:
1. Do not use breadcrumbs as a substitute for the main menu
This might seem obvious, but it’s essential to mention. Treat breadcrumbs as an additional feature and not as a substitute for the main navigation menu on your WordPress site.
Think of breadcrumbs as a convenience element, a secondary menu, or an alternative way to navigate on your site.
2. Do not add a link to the current page in the navigation
The last item in breadcrumbs is optional, but if you choose to display it, ensure it is not clickable. Since the user is already on the current page, it makes no sense to add a link to the page they are already on.
3. Use separator lines
The most common separator in breadcrumbs is the “greater than” sign ( > ). The sign is intended to indicate hierarchy, such as the format Parent Category > Subcategory.
Other symbols in use include arrows, slashes, and more. The choice of which to use is based on aesthetics and the type of breadcrumbs in use.
4. Use Appropriate Sizes and Spacing
Pay attention to the size of the clickable link and the spacing when designing. There should be sufficient space between breadcrumb levels; otherwise, it will be challenging for the user to use them.
Simultaneously, ensure that the breadcrumb element does not dominate the page—it should be safely less dominant than the main navigation menu.
5. Ensure Breadcrumbs Are Not the Focal Point
As a general rule, when designing breadcrumbs on your page, ensure that the element is not the first to catch the eye and capture attention. If you make breadcrumbs too prominent, they may divert attention from the main menu or content, which is not the goal.
Take note of how Amazon displays breadcrumbs in the following example. They are not overly attention-grabbing but still easy for users to identify and navigate through.
6. Optional Use of Breadcrumbs on Mobile Sites
Regarding mobile sites, if you find that you need breadcrumbs for navigation, something might be wrong with the design of your mobile site.
It’s possible that your site is too complex for this environment, and initially, it would be right to solve the problem and simplify the site structure in the mobile environment so that breadcrumbs are not on the agenda. Despite this, if you can add breadcrumbs to mobile, it probably won’t hurt.
How to Add Breadcrumbs on WordPress Sites?
There are quite a few plugins that allow adding breadcrumbs on WordPress sites, but they may not always be the right option as they may not work correctly or may not fit the requirements of your WordPress site or your theme.
During my searches, I found a wonderful post that explains how to add breadcrumbs to a WordPress site without a plugin in just a few seconds. The post’s function is very versatile and supports:
- Parent and child pages
- Archive pages
- Custom post types
- Custom taxonomies
Copy this code into your theme’s child template functions.php
file (make sure to remove the opening PHP tag if copying):
<?php
/******** BEGIN HERE ********/
function custom_breadcrumbs() {
// Settings
$separator = '>';
$breadcrumbs_id = 'breadcrumbs';
$breadcrumbs_class = 'breadcrumbs';
$home_title = 'Homepage';
// If you have any custom post types with custom taxonomies, put the taxonomy name below (e.g. product_cat)
$custom_taxonomy = 'product_cat';
// Get the query & post information
global $post, $wp_query;
// Do not display on the homepage
if ( ! is_front_page() ) {
// Build the breadcrumbs
echo '<ul id="' . $breadcrumbs_id . '" class="' . $breadcrumbs_class . '">';
// 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_archive() && ! is_tax() && ! is_category() && ! is_tag() ) {
echo '<li class="item-current item-archive"><strong class="bread-current bread-archive">' . post_type_archive_title( $prefix, false ) . '</strong></li>';
} else if ( is_archive() && is_tax() && ! is_category() && ! is_tag() ) {
// If post is a custom post type
$post_type = get_post_type();
// If it is a custom post type display name and link
if ( $post_type != 'post' ) {
$post_type_object = get_post_type_object( $post_type );
$post_type_archive = get_post_type_archive_link( $post_type );
echo '<li class="item-cat item-custom-post-type-' . $post_type . '"><a class="bread-cat bread-custom-post-type-' . $post_type . '" href="' . $post_type_archive . '" title="' . $post_type_object->labels->name . '">' . $post_type_object->labels->name . '</a></li>';
echo '<li class="separator"> ' . $separator . '</li>';
}
$custom_tax_name = get_queried_object()->name;
echo '<li class="item-current item-archive"><strong class="bread-current bread-archive">' . $custom_tax_name . '</strong></li>';
} else if ( is_single() ) {
// If post is a custom post type
$post_type = get_post_type();
// If it is a custom post type display name and link
if ( $post_type != 'post' ) {
$post_type_object = get_post_type_object( $post_type );
$post_type_archive = get_post_type_archive_link( $post_type );
echo '<li class="item-cat item-custom-post-type-' . $post_type . '"><a class="bread-cat bread-custom-post-type-' . $post_type . '" href="' . $post_type_archive . '" title="' . $post_type_object->labels->name . '">' . $post_type_object->labels->name . '</a></li>';
echo '<li class="separator"> ' . $separator . '</li>';
}
// Get post category info
$category = get_the_category();
if ( ! empty( $category ) ) {
// Get last category post is in
$last_category = end( array_values( $category ) );
// Get parent any categories and create array
$get_cat_parents = rtrim( get_category_parents( $last_category->term_id, true, ',' ), ',' );
$cat_parents = explode( ',', $get_cat_parents );
// Loop through parent categories and store in variable $cat_display
$cat_display = '';
foreach ( $cat_parents as $parents ) {
$cat_display .= '<li class="item-cat">' . $parents . '</li>';
$cat_display .= '<li class="separator"> ' . $separator . '</li>';
}
}
// If it's a custom post type within a custom taxonomy
$taxonomy_exists = taxonomy_exists( $custom_taxonomy );
if ( empty( $last_category ) && ! empty( $custom_taxonomy ) && $taxonomy_exists ) {
$taxonomy_terms = get_the_terms( $post->ID, $custom_taxonomy );
$cat_id = $taxonomy_terms[0]->term_id;
$cat_nicename = $taxonomy_terms[0]->slug;
$cat_link = get_term_link( $taxonomy_terms[0]->term_id, $custom_taxonomy );
$cat_name = $taxonomy_terms[0]->name;
}
// Check if the post is in a category
if ( ! empty( $last_category ) ) {
echo $cat_display;
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 post is in a custom taxonomy
} else if ( ! empty( $cat_id ) ) {
echo '<li class="item-cat item-cat-' . $cat_id . ' item-cat-' . $cat_nicename . '"><a class="bread-cat bread-cat-' . $cat_id . ' bread-cat-' . $cat_nicename . '" href="' . $cat_link . '" title="' . $cat_name . '">' . $cat_name . '</a></li>';
echo '<li class="separator"> ' . $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 {
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"><strong class="bread-current bread-cat">' . single_cat_title( '', false ) . '</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
if ( ! isset( $parents ) ) {
$parents = null;
}
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 );
$get_term_id = $terms[0]->term_id;
$get_term_slug = $terms[0]->slug;
$get_term_name = $terms[0]->name;
// Display the tag name
echo '<li class="item-current item-tag-' . $get_term_id . ' item-tag-' . $get_term_slug . '"><strong class="bread-current bread-tag-' . $get_term_id . ' bread-tag-' . $get_term_slug . '">' . $get_term_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' ) . ' Archive</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' ) . ' Archive</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' ) . ' Archive</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' ) . ' Archive</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' ) . ' Archive</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' ) . ' Archive</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>';
}
}
Pay attention that in line number 8, you have the option to change the name that will appear for the homepage in the breadcrumbs.
To call the function in your template, use the following code. Usually, the function call is placed in either the single.php
file or in header.php
:
<?php custom_breadcrumbs(); ?>
To style the breadcrumbs, you can start from here:
#breadcrumbs{
list-style:none;
margin:10px 0;
overflow:hidden;
}
#breadcrumbs li{
display:inline-block;
vertical-align:middle;
margin-right: 5px;
}
#breadcrumbs .separator{
font-size:18px;
font-weight:100;
color:#ccc;
}
Since WordPress installations or themes may vary, you might need to adjust the code slightly for it to work correctly. Please let me know in the comments if you encounter a white screen or any PHP error. If you have the time and inclination to improve the code, I would appreciate it if you could send it to me, and you will receive the credit you deserve. 🙂
If you are not experienced with code or prefer not to deal with it, it is recommended to use a plugin like Yoast SEO to achieve this, as shown in the next section…
Adding Breadcrumbs Using WordPress SEO by Yoast
Yoast has a built-in breadcrumb mechanism that works excellently. To add them using the plugin, you need to enable their functionality in Yoast’s control panel under Yoast SEO > Settings > Advanced. Then navigate to the Breadcrumbs tab and activate the option “Enable breadcrumbs for your theme” at the bottom.
Yoast allows you to easily customize breadcrumb settings.
Note that the plugin lets you specify which taxonomy to display in the breadcrumbs. In this blog, for example, there is a taxonomy named “My Category” that behaves similarly to the default “Categories” taxonomy in WordPress and is used to categorize posts on the site.
These are essentially the categories you see in the top menu or sidebar of the blog.
I would be happy to explain why I did this, but it’s a topic on its own. In general, a poorly planned structure of links and categories at the beginning of the blog’s journey. The conclusion in a nutshell is that it’s better not to display categories in the link structure (as is the case with this blog).
In any case, the Yoast plugin makes it very easy. To display the breadcrumbs, use the following code wherever you want in your WordPress template, usually in the single.php
file or sometimes in header.php
in such custom themes:
if ( function_exists( 'yoast_breadcrumb' ) ) {
yoast_breadcrumb();
}
You can also use a shortcode [wpseo_breadcrumb] to display breadcrumbs, as I do here:
Advantages of Using Breadcrumbs for SEO
There are several advantages to using breadcrumbs, and their proper addition is an integral part of the important Technical SEO process:
A. Google Likes Breadcrumbs
Breadcrumbs help both users on your site and Google better understand the hierarchical structure of your site. If you have implemented correct structured data or if you are using Yoast to embed breadcrumbs, Google may display them in search results.
This display will highlight your link in Google search results, and it is reasonable to assume that many more people will click on those results, leading to a higher Click-Through Rate (CTR).
B. Breadcrumbs Improve User Experience
No one likes to be lost. Just as a person arriving at a new place looks around and searches for landmarks and signs to rely on to find their way, a user landing on your site behaves in a similar way.
Breadcrumbs enhance the user experience, and being familiar to everyone helps in navigating your site without wasting thought or time searching for a navigation solution. They help keep your visitors happy and reduce friction with them.
C. They Reduce Bounce Rate
As mentioned at the beginning of the article, not many visitors land on your homepage. Most visitors come to your site through organic search, making each page on your site a potential entry point for the visitor.
It would be right to allow the same visitor to go to other parts of your site easily and quickly. This action will reduce your site’s bounce rate simply by providing an additional and simple alternative for site navigation.
Of course, it’s better that they do this on your site rather than going back to Google to search for something else or another topic or product that exists on your site…
Conclusion
Despite the breadcrumbs left by me and Tami, they still got lost in the forest. Don’t let this happen to your visitors.
Adding breadcrumbs to WordPress sites provides a simple way for users to navigate your site, and those users (just like Google) quickly understand the structure of your site and feel a sense of home… and who doesn’t love home? 😉