Breadcrumbs are essential for enhancing user navigation on your website. They provide a clear path for visitors to understand their location within your site’s hierarchy. While there are several plugins available for adding breadcrumbs in WordPress, using custom code can be more efficient and lightweight. In this guide, I’ll show you how to create custom breadcrumbs without relying on additional plugins.
Table of Contents
First, open your WordPress theme’s functions.php
file. You can find this file in your theme directory. Add the following custom code snippet to the file:
// Start SV Breadcrumbs function sv_custom_breadcrumbs() { ob_start(); // Settings $separator = '>'; $breadcrums_id = 'sv_custom_breadcrumbs'; $breadcrums_class = 'sv_custom_breadcrumbs'; $home_title = 'Home'; // 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 breadcrums echo '<div id="' . $breadcrums_id . '" class="' . $breadcrums_class . '">'; if (is_search()) { echo '<h2><strong>' . get_search_query() . '</strong></h2> <br />'; } else { echo '<h2><strong>' . get_the_title() . '</strong></h2> <br />'; } echo '<ul>'; // Home page echo '<li class="item-home"><a class="bread-link bread-home" href="' . get_home_url() . '" >' . $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"><h2><strong class="bread-current bread-archive">' . post_type_archive_title('', false) . '</strong></h2></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"><h2><strong class="bread-current bread-archive">' . $custom_tax_name . '</strong></h2></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>'; } // 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 . '"><h2><strong class="bread-current bread-' . $post->ID . '" title="' . get_the_title() . '">' . get_the_title() . '</strong></h2></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 . '"><h2><strong class="bread-current bread-' . $post->ID . '" title="' . get_the_title() . '">' . get_the_title() . '</strong></h2></li>'; } else { echo '<li class="item-current item-' . $post->ID . '"><h2><strong class="bread-current bread-' . $post->ID . '" title="' . get_the_title() . '">' . get_the_title() . '</strong></h></li>'; } } else if (is_category()) { // Category page echo '<li class="item-current item-cat"><h2><strong class="bread-current bread-cat">' . single_cat_title('', false) . '</strong></h2></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) . '" >' . 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 . '"><h2><strong title="' . get_the_title() . '"> ' . get_the_title() . '</strong></h2></li>'; } else { // Just display current page if not parents echo '<li class="item-current item-' . $post->ID . '"><h2><strong class="bread-current bread-' . $post->ID . '"> ' . get_the_title() . '</strong></h2></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 . '"><h2><strong class="bread-current bread-tag-' . $get_term_id . ' bread-tag-' . $get_term_slug . '">' . $get_term_name . '</strong></h2></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') . '"><h2><strong class="bread-current bread-' . get_the_time('j') . '"> ' . get_the_time('jS') . ' ' . get_the_time('M') . ' Archives</strong></h2></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') . '"><h2><strong class="bread-month bread-month-' . get_the_time('m') . '" title="' . get_the_time('M') . '">' . get_the_time('M') . ' Archives</strong></h2></li>'; } else if (is_year()) { // Display year archive echo '<li class="item-current item-current-' . get_the_time('Y') . '"><h2><strong class="bread-current bread-current-' . get_the_time('Y') . '" title="' . get_the_time('Y') . '">' . get_the_time('Y') . ' Archives</strong></h2></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 . '"><h2><strong class="bread-current bread-current-' . $userdata->user_nicename . '" title="' . $userdata->display_name . '">' . 'Author: ' . $userdata->display_name . '</strong></h2></li>'; } else if (get_query_var('paged')) { // Paginated archives echo '<li class="item-current item-current-' . get_query_var('paged') . '"><h2><strong class="bread-current bread-current-' . get_query_var('paged') . '" title="Page ' . get_query_var('paged') . '">' . __('Page') . ' ' . get_query_var('paged') . '</strong></h2></li>'; } else if (is_search()) { // Search results page echo '<li class="item-current "><h2><strong class="bread-current " title="Search results for: ' . get_search_query() . '">Search results for: ' . get_search_query() . '</strong></h2></li>'; } elseif (is_404()) { // 404 page echo '<li>' . 'Error 404' . '</li>'; } echo '</ul>'; echo '</div>'; } $breadcrums = ob_get_clean(); return $breadcrums; } add_shortcode('sv-breadcrumbs', 'sv_custom_breadcrumbs'); // End SV Breadcrumbs
.custom_breadcrumbs { list-style: none; padding: 0; margin: 0; } .custom_breadcrumbs li { display: inline-block; } .custom_breadcrumbs li a { text-decoration: none; color: #333; padding: 5px 10px; } .custom_breadcrumbs li a:hover { color: #000; } .custom_breadcrumbs li:after { content: ">"; padding: 0 5px; color: #ccc; } .custom_breadcrumbs li:last-child:after { content: ""; }
Now that you’ve added the custom code, you can display the breadcrumbs on your website. There are two methods to achieve this:
If you want to display breadcrumbs within your posts or pages, use the [sv-breadcrumbs]
shortcode. Simply insert this shortcode where you want the breadcrumb trail to appear.
For more flexibility, you can directly call the sv_custom_breadcrumbs()
function in your theme files. For instance, add the following code snippet to your template files (e.g., header.php
, single.php
, etc.):
echo sv_custom_breadcrumbs();
By following these steps, you can create custom breadcrumbs tailored to your website’s structure. Remember that well-implemented breadcrumbs not only improve user experience but also enhance your site’s SEO. Happy coding!
Feel free to customize the code further based on your specific requirements. If you have any questions or need additional assistance, feel free to ask! 😊