Web20 University

Implementing WordPress Breadcrumbs Without a Plugin: A Step-by-Step Guide

Get Up to 65% Off PHP Hosting and Free Domains!

TL;DR

You can create breadcrumbs on your WordPress site by creating your own function to generate the links to the hierarchy of your pages but there are a lot of things to consider like what category of page is currently being viewed..

You can do this with a plugin however this article will walk you through creating your own custom code to do this.

Do You Need a Plugin for WordPress Breadcrumbs?

The short answer is no, you don’t necessarily need a plugin to add breadcrumbs to your WordPress site. While plugins offer a quick and easy solution, implementing breadcrumbs manually gives you more control over their appearance and functionality and being able to work with the different WordPress built-in functions is a key skill for WordPress developers.

How to Add WordPress Breadcrumbs Without a Plugin

Let’s walk through the process of adding breadcrumbs to your WordPress theme without using a plugin:

  1. Open your theme’s functions.php file.

  2. Add the following function to create the breadcrumbs:

function custom_breadcrumbs() {
    // Set variables for current page
    $home_link = home_url('/');
    $home_text = __('Home');
    $link_before = '<span typeof="v:Breadcrumb">';
    $link_after = '</span>';
    $link_attr = ' rel="v:url" property="v:title"';
    $link = $link_before . '<a' . $link_attr . ' href="%1$s">%2$s</a>' . $link_after;
    $delimiter = ' &raquo; '; // Delimiter between crumbs
    $before = '<span class="current">'; // Tag before the current crumb
    $after = '</span>'; // Tag after the current crumb
    $page_addon = ''; // Adds the page number if the query is paginated
    $breadcrumb_trail = '';
    $category_links = '';

    /** 
     * Set our own $wp_the_query variable. Do not use the global variable version due to 
     * reliability
     */
    $wp_the_query = $GLOBALS['wp_the_query'];
    $queried_object = $wp_the_query->get_queried_object();

    // Handle single post requests
    if (is_singular()) {
        $post_object = sanitize_post($queried_object);
        $title = apply_filters('the_title', $post_object->post_title);
        $parent = $post_object->post_parent;
        $post_type = $post_object->post_type;
        $post_id = $post_object->ID;
        $post_link = $before . $title . $after;
        $parent_string = '';
        $post_type_link = '';

        if ($post_type === 'post') {
            $categories = get_the_category($post_id);
            if ($categories) {
                $category = $categories[0];
                $category_links = get_category_parents($category, true, $delimiter);
                $category_links = str_replace('<a', $link_before . '<a' . $link_attr, $category_links);
                $category_links = str_replace('</a>', '</a>' . $link_after, $category_links);
            }
        }

        if (!empty($parent)) {
            $parent_links = array();
            while ($parent) {
                $post_parent = get_post($parent);
                $parent_links[] = sprintf($link, esc_url(get_permalink($post_parent->ID)), get_the_title($post_parent->ID));
                $parent = $post_parent->post_parent;
            }
            $parent_links = array_reverse($parent_links);
            $parent_string = implode($delimiter, $parent_links);
        }

        // Render the breadcrumb trail
        $breadcrumb_trail = $parent_string . $category_links . $post_link;
    } elseif (is_archive() && !is_tax() && !is_category() && !is_tag()) {
        $post_type = $wp_the_query->query_vars['post_type'];
        if ($post_type) {
            $post_type_object = get_post_type_object($post_type);
            $breadcrumb_trail = $before . $post_type_object->labels->singular_name . $after;
        }
    } elseif (is_category()) {
        $cat_obj = $queried_object;
        $category_links = get_category_parents($cat_obj->term_id, true, $delimiter);
        $category_links = str_replace('<a', $link_before . '<a' . $link_attr, $category_links);
        $category_links = str_replace('</a>', '</a>' . $link_after, $category_links);
        $breadcrumb_trail = $category_links;
    } elseif (is_page()) {
        $parent = $queried_object->post_parent;
        if ($parent) {
            $parent_links = array();
            while ($parent) {
                $post_parent = get_post($parent);
                $parent_links[] = sprintf($link, esc_url(get_permalink($post_parent->ID)), get_the_title($post_parent->ID));
                $parent = $post_parent->post_parent;
            }
            $parent_links = array_reverse($parent_links);
            $parent_string = implode($delimiter, $parent_links);
        }
        $breadcrumb_trail = $parent_string . $before . get_the_title() . $after;
    } elseif (is_tag()) {
        $breadcrumb_trail = $before . 'Posts tagged "' . single_tag_title('', false) . '"' . $after;
    } elseif (is_author()) {
        $breadcrumb_trail = $before . 'Author: ' . get_the_author() . $after;
    } elseif (is_404()) {
        $breadcrumb_trail = $before . 'Error 404' . $after;
    } elseif (is_home()) {
        $breadcrumb_trail = $before . 'Blog' . $after;
    }

    if (get_query_var('paged')) {
        $breadcrumb_trail .= ' (' . __('Page') . ' ' . get_query_var('paged') . ')';
    }

    // Build the breadcrumb trail
    $breadcrumb_output = '<div class="breadcrumbs" xmlns:v="http://rdf.data-vocabulary.org/#">';
    if (is_home() || is_front_page()) {
        // Do not show breadcrumbs on home page
        $breadcrumb_output = '';
    } else {
        $breadcrumb_output .= sprintf($link, $home_link, $home_text) . $delimiter . $breadcrumb_trail;
    }
    $breadcrumb_output .= '</div>';

    return $breadcrumb_output;
}
  1. Now, add this function call where you want the breadcrumbs to appear in your theme files (e.g., header.php, single.php, page.php):
<?php echo custom_breadcrumbs(); ?>
  1. Style your breadcrumbs by adding CSS to your theme’s stylesheet:
.breadcrumbs {
    padding: 10px 0;
    margin-bottom: 20px;
    font-size: 14px;
}
.breadcrumbs a {
    color: #007bff;
    text-decoration: none;
}
.breadcrumbs a:hover {
    text-decoration: underline;
}
.breadcrumbs .current {
    font-weight: bold;
}

Is It Better to Use a Plugin?

Whether to use a plugin or implement breadcrumbs manually depends on your specific needs:

Advantages of manual implementation:

  • Greater control over functionality and appearance
  • No additional plugin overhead
  • Can be customized to fit your exact requirements

Advantages of using a plugin:

  • Easier to implement, especially for non-developers
  • Often includes additional features and options
  • Regularly updated to maintain compatibility with WordPress core

For simple websites or experienced developers, manual implementation might be preferable. For complex sites or those needing advanced features, a plugin could be the better choice.

If you decide to use a plugin, here are some popular options:

  1. Yoast SEO: Includes breadcrumb functionality along with comprehensive SEO features.
  2. Breadcrumb NavXT: A dedicated breadcrumb plugin with extensive customization options.
  3. SEOPress: Another SEO plugin that includes breadcrumb functionality.
  4. Slim SEO: A lightweight SEO plugin that also offers breadcrumb features.

Conclusion

Implementing WordPress breadcrumbs without a plugin is entirely possible and gives you fine-grained control over their appearance and functionality. However, for those less comfortable with code or needing advanced features, plugins offer a viable alternative. Whichever method you choose, breadcrumbs can significantly enhance your site’s navigation and user experience.

Remember to test your breadcrumbs thoroughly across different page types and ensure they’re responsive on various screen sizes.

Get Up to 65% Off PHP Hosting and Free Domains!