Type something to search...
How to Add Breadcrumbs in WordPress?

How to Add Breadcrumbs in WordPress?

Breadcrumbs are the small trail of links near the top of a page that show a visitor exactly where they are, something like Home > Blog > WordPress > How to Add Breadcrumbs. They look like a small detail, but they solve a real problem: once a visitor lands deep inside your site from a search result or a social share, breadcrumbs are what let them understand the page's context and navigate up a level without hitting the back button.

Breadcrumbs matter for search engines too. Google frequently displays them directly in search results in place of a plain URL, and structured breadcrumb data helps Google understand your site's hierarchy when crawling it. WordPress doesn't include breadcrumbs out of the box, so in this guide, you'll add them two ways: through your existing SEO plugin (the fastest route for most sites), and with your own code if you want full control or don't have an SEO plugin installed.

Why Add Breadcrumbs to Your WordPress Site?

Before diving into implementation, here's what you actually gain:

  • Easier navigation for visitors. Someone landing on a single product or blog post from Google can jump straight back to the category or archive it belongs to, in one click.
  • Lower bounce rates. Visitors who can see a path back to related content are more likely to keep browsing instead of leaving entirely.
  • Rich snippets in search results. With valid BreadcrumbList structured data, Google often replaces the plain URL under your search listing with your breadcrumb trail, which is both more useful and more clickable.
  • A clearer site structure for search engines. Consistent breadcrumbs reinforce the parent-child relationships between your pages, categories, and posts.

Option 1: Use Your SEO Plugin's Built-In Breadcrumbs

If you're already running Yoast SEO or Rank Math, you almost certainly already have a breadcrumbs feature sitting unused, since both plugins generate valid BreadcrumbList schema automatically once enabled.

With Yoast SEO

  1. Go to Yoast SEO → Settings in your dashboard.
  2. Open the Breadcrumbs section (under the site-wide settings tab).
  3. Toggle Enable Breadcrumbs to on, then configure the separator, the "Home" text, and whether to show the current page as the last (unlinked) item.
  4. Save your changes.

Yoast doesn't insert the breadcrumbs into your theme automatically; you need to add one line to your theme where you want them to appear, typically right above the page title in single.php, page.php, and archive.php:

<?php
if ( function_exists( 'yoast_breadcrumb' ) ) {
    yoast_breadcrumb( '<p id="breadcrumbs">', '</p>' );
}
?>

The two arguments are the opening and closing HTML wrapped around the trail, so you can target #breadcrumbs in your CSS without any extra markup.

With Rank Math

  1. Go to Rank Math → General Settings → Breadcrumbs.
  2. Toggle breadcrumbs on, and configure the separator and labels the same way as Yoast.
  3. Save your changes.

Rank Math exposes a matching template tag for your theme:

<?php
if ( function_exists( 'rank_math_the_breadcrumbs' ) ) {
    rank_math_the_breadcrumbs();
}
?>

Both plugins also expose a shortcode ([wpseo_breadcrumb] for Yoast, [rank_math_breadcrumb] for Rank Math) if you'd rather drop breadcrumbs into a specific page's content, or into a block theme using the Shortcode block, instead of editing template files directly.

Option 2: Add Breadcrumbs With Your Own Code

If you don't want to rely on an SEO plugin, or you need breadcrumbs styled and structured exactly your own way, you can build them yourself. This is also the right option if your SEO plugin's breadcrumb output doesn't quite match your site's structure (for example, a custom post type with a non-standard hierarchy).

Step 1: Add the Breadcrumb Function

Add this to your theme's functions.php, or better, a must-use plugin so it isn't lost on a theme switch:

function tidewave_breadcrumbs() {
    if ( is_front_page() ) {
        return;
    }

    echo '<nav class="breadcrumbs" aria-label="Breadcrumb"><ol>';

    echo '<li><a href="' . esc_url( home_url( '/' ) ) . '">Home</a></li>';

    if ( is_category() || is_single() ) {
        echo '<li>' . get_the_category_list( ', ' ) . '</li>';

        if ( is_single() ) {
            echo '<li aria-current="page">' . esc_html( get_the_title() ) . '</li>';
        }
    } elseif ( is_page() ) {
        $post = get_queried_object();

        if ( $post->post_parent ) {
            $ancestors = array_reverse( get_post_ancestors( $post->ID ) );

            foreach ( $ancestors as $ancestor_id ) {
                echo '<li><a href="' . esc_url( get_permalink( $ancestor_id ) ) . '">' . esc_html( get_the_title( $ancestor_id ) ) . '</a></li>';
            }
        }

        echo '<li aria-current="page">' . esc_html( get_the_title() ) . '</li>';
    } elseif ( is_tag() ) {
        echo '<li aria-current="page">Tag: ' . esc_html( single_tag_title( '', false ) ) . '</li>';
    } elseif ( is_author() ) {
        echo '<li aria-current="page">Author: ' . esc_html( get_the_author() ) . '</li>';
    } elseif ( is_day() ) {
        echo '<li aria-current="page">' . esc_html( get_the_date() ) . '</li>';
    } elseif ( is_month() ) {
        echo '<li aria-current="page">' . esc_html( get_the_date( 'F Y' ) ) . '</li>';
    } elseif ( is_year() ) {
        echo '<li aria-current="page">' . esc_html( get_the_date( 'Y' ) ) . '</li>';
    } elseif ( is_search() ) {
        echo '<li aria-current="page">Search results for: ' . esc_html( get_search_query() ) . '</li>';
    } elseif ( is_404() ) {
        echo '<li aria-current="page">404 Not Found</li>';
    } elseif ( is_archive() ) {
        echo '<li aria-current="page">' . esc_html( get_the_archive_title() ) . '</li>';
    }

    echo '</ol></nav>';
}

This covers every common context WordPress can render: single posts (with their category), pages (including nested pages, by walking up get_post_ancestors()), tag and author archives, date archives, search results, and a 404 fallback.

Step 2: Call It From Your Templates

Add this wherever you want the trail to appear, typically just inside <main>, above the page title:

<?php if ( function_exists( 'tidewave_breadcrumbs' ) ) : ?>
    <?php tidewave_breadcrumbs(); ?>
<?php endif; ?>

Add it to single.php, page.php, archive.php, search.php, and 404.php individually, or once to a shared header.php if your theme's header already knows which template is loading.

Step 3: Style the Breadcrumb Trail

.breadcrumbs ol {
    display: flex;
    flex-wrap: wrap;
    list-style: none;
    margin: 0 0 24px;
    padding: 0;
    font-size: 14px;
    color: #717171;
}

.breadcrumbs li {
    display: flex;
    align-items: center;
}

.breadcrumbs li:not(:last-child)::after {
    content: "/";
    margin: 0 8px;
    color: #b4afb6;
}

.breadcrumbs a {
    color: #5b4fe0;
    text-decoration: none;
}

.breadcrumbs a:hover {
    text-decoration: underline;
}

.breadcrumbs li[aria-current="page"] {
    color: #444444;
    font-weight: 500;
}

Adding BreadcrumbList Structured Data

The HTML breadcrumbs above are enough for visitors, but to get the rich snippet treatment in Google search results, you need to output matching BreadcrumbList JSON-LD alongside them. If you're using Yoast or Rank Math, this is already handled for you. If you built your own breadcrumbs in Option 2, add this function too:

function tidewave_breadcrumb_schema() {
    if ( is_front_page() ) {
        return;
    }

    $items = [
        [
            'name' => 'Home',
            'url'  => home_url( '/' ),
        ],
    ];

    if ( is_single() ) {
        $categories = get_the_category();

        if ( ! empty( $categories ) ) {
            $items[] = [
                'name' => $categories[0]->name,
                'url'  => get_category_link( $categories[0]->term_id ),
            ];
        }

        $items[] = [
            'name' => get_the_title(),
            'url'  => get_permalink(),
        ];
    } elseif ( is_page() ) {
        $ancestors = array_reverse( get_post_ancestors( get_queried_object_id() ) );

        foreach ( $ancestors as $ancestor_id ) {
            $items[] = [
                'name' => get_the_title( $ancestor_id ),
                'url'  => get_permalink( $ancestor_id ),
            ];
        }

        $items[] = [
            'name' => get_the_title(),
            'url'  => get_permalink(),
        ];
    }

    if ( count( $items ) < 2 ) {
        return;
    }

    $list_items = [];

    foreach ( $items as $position => $item ) {
        $list_items[] = [
            '@type'    => 'ListItem',
            'position' => $position + 1,
            'name'     => $item['name'],
            'item'     => $item['url'],
        ];
    }

    $schema = [
        '@context'        => 'https://schema.org',
        '@type'           => 'BreadcrumbList',
        'itemListElement' => $list_items,
    ];

    echo '<script type="application/ld+json">' . wp_json_encode( $schema ) . '</script>';
}
add_action( 'wp_head', 'tidewave_breadcrumb_schema' );

Hooking this to wp_head means it outputs automatically on every page load, without needing to be called from your templates directly. Once it's live, validate it with Google's Rich Results Test by entering one of your post URLs, since a schema error here won't break your page but will silently disqualify you from the rich snippet.

Breadcrumbs in Block Themes (Full Site Editing)

If you're using a block theme, you won't be editing single.php or page.php directly. Instead:

  1. Open the Site Editor and edit the template you want breadcrumbs on (for example, Single Posts).
  2. Add a Shortcode block where you want the trail to appear.
  3. Enter [wpseo_breadcrumb] or [rank_math_breadcrumb], depending on which SEO plugin you have active.

If you're not using either plugin, the custom function from Option 2 still works in a block theme; just wrap the function call in a small shortcode instead, since block templates don't support raw PHP calls directly:

add_shortcode( 'tidewave_breadcrumbs', function () {
    ob_start();
    tidewave_breadcrumbs();
    return ob_get_clean();
} );

Then use [tidewave_breadcrumbs] in a Shortcode block the same way you would with a plugin's shortcode.

Frequently Asked Questions (FAQ) About WordPress Breadcrumbs

Not directly as a ranking factor, but they improve two things that do influence rankings indirectly: how long visitors stay on your site (by making it easier to keep browsing), and how well Google understands your site's structure when crawling it. The rich snippet they can unlock in search results also tends to improve click-through rate.

No, most sites skip breadcrumbs on the homepage since there's no parent page above it to reference. Both the code example and most SEO plugins already check is_front_page() and return early for exactly this reason.

Not necessarily. If your existing breadcrumbs already output valid BreadcrumbList schema and match your site's hierarchy, there's no need to replace them. Check the page source for a script type="application/ld+json" block containing "@type": "BreadcrumbList" to confirm the schema is present.

Yes. WooCommerce ships with its own woocommerce_breadcrumb() template tag that follows the same pattern as the examples above, and most WooCommerce themes already call it inside the single product template. If you're using Yoast or Rank Math, their breadcrumb settings apply to WooCommerce pages automatically as well.

Both the display function and the schema function above use the post's primary category if one is set (which Yoast and Rank Math both let you choose per post), or the first category returned otherwise. If a post is miscategorized in your breadcrumb trail, check whether it has an unintended primary category set, or simply has too many categories assigned.

You can, but only one should actually render on the page, and only one should output BreadcrumbList schema. Having two competing schema blocks on the same page is invalid and can confuse Google's structured data parsing, so pick one source of truth per site.

Conclusion

Breadcrumbs are a small addition with a disproportionate payoff: a few minutes of setup gets your visitors an easier way to navigate, and gets your search listings a shot at the more clickable rich-snippet treatment in Google. If you already run Yoast SEO or Rank Math, enabling their built-in breadcrumbs and adding one template tag is by far the fastest path. If you'd rather not depend on a plugin, the custom function and schema code above give you the exact same result, with full control over the markup, styling, and which page types get a trail at all.

Whichever path you take, validate the result with Google's Rich Results Test once it's live, since that's the only way to confirm your BreadcrumbList schema is actually eligible for the search snippet, not just present on the page.

Here are a few additional resources if you want to go deeper:

Tags :
Share :

Related Posts

Effortlessly Crafting Compelling WordPress Pages

Effortlessly Crafting Compelling WordPress Pages

As a website owner or content creator, having the ability to seamlessly add new pages to your WordPress site is crucial. Whether you're introducing a

Continue Reading
High Traffic Tips for WordPress Mastery 🚥

High Traffic Tips for WordPress Mastery 🚥

In our digital age, where online visibility is paramount, ensuring your WordPress site can handle surging traffic is crucial. Just like a finely-tune

Continue Reading
How Do I Change the WordPress Login URL?

How Do I Change the WordPress Login URL?

By default, every WordPress site's login page lives at the same predictable address: yoursite.com/wp-login.php (which also happens to redirect from

Continue Reading