How to Get Yoast’s Primary Category

Edit: Yoast now has an internal function, yoast_get_primary_term_id(), that provides the primary term for a specific post.

Displaying WordPress categories in a theme can be a challenge because a post could belong to several different categories and if the theme has to display 30 categories for each post in a list, it could get messy. This is where a primary category comes in handy.

Often I find myself needing to find the most important category for a blog post when a site was only designed to show one or a client likes to add 15 different categories.

Yoast SEO is a great plugin for managing general SEO for WordPress, but it also provides a handy feature that can easily be overlooked. If multiple categories have been selected for a blog post, it will designate the first selected category as the “Primary Category”.

Since Yoast handles selecting this primary category, we can hook in and grab it without too much trouble. Here’s a basic layout of what this function will do for us:

/**
 * Gets the primary category set by Yoast SEO.
 *
 * @return array The category name, slug, and URL.
 */
function get_primary_category( $post = 0 ) {
	if ( ! $post ) {
		$post = get_the_ID();
	}
	
	// Get the categories for the post.
	$category = get_the_category( $post );

	// If post has a category assigned.
	if ($category){
		if ( class_exists('WPSEO_Primary_Term') )
		{
			// Show the post's 'Primary' category, if this Yoast feature is available, & one is set

			if (is_wp_error($term)) {
				// Default to first category (not Yoast) if an error is returned
			} else {
				// Yoast Primary category goodness
			}
		}
		else {
			// Default, display the first category in WP's list of assigned categories
	}
	return $primary_category;
}

First, we check if a $post ID has been passed (if we ever need to find the primary category of a post outside of the loop). If no ID was passed then we need to get the current post’s ID since we can assume we’re inside the loop.

if ( ! $post ) {
	$post = get_the_ID();
}

Next, we’ll use get_the_category() to retrieve all the current posts categories. We also set up an empty array that we’ll use to store the primary category’s information.

$category = get_the_category( $post );
$primary_category = array();

Once we have all the categories currently assigned to the post, we’ll check to see if there’s only one listed because we can skip this whole process if there’s only one category assigned.

// If the post has more than one category assigned to it.
if ( 1 > count($category) ){
  // Set up the necessary variables.
  $category_display = '';
  $category_slug = '';
  $category_link = '';
  
  // Grab Yoast's reference to the 'Primary Category'.
  
}

Make sure the Yoast plugin is installed and if the WPSEO_Primary_Term class doesn’t exist,  just use the first category in the list.

It’s not the best fallback option because WordPress displays the categories in alphabetical order. So it wouldn’t serve as the best primary category, but it serves our purpose for now.

if ( class_exists('WPSEO_Primary_Term') ) {
  
	// Use the class to grab the primary category.
	
}
else {
	// Display the first category in WordPress' list of assigned categories
	$category_display = $category[0]->name;
	$category_slug = $category[0]->slug;
	$category_link = get_category_link( $category[0]->term_id );
}

Finally we’ll grab the category using the WPSEO_Primary_Term class:

// Get the primary category for the current post.
$wpseo_primary_term = new WPSEO_Primary_Term( 'category', $post );
$wpseo_primary_term = $wpseo_primary_term->get_primary_term();
$term = get_term( $wpseo_primary_term );

if (is_wp_error($term)) {
  // Default to first category (not Yoast) if an error is returned
  $category_display = $category[0]->name;
  $category_slug = $category[0]->slug;
  $category_link = get_category_link( $category[0]->term_id );
} else {
  // Yoast Primary category goodness
  $category_display = $term->name;
  $category_slug = $term->slug;
  $category_link = get_category_link( $term->term_id );
}

Now that we have the primary category, we can have the function return or echo it out depending on how it is used in our blog.

Here’s the whole function if you just want to paste this into your current project:

22 responses to “How to Get Yoast’s Primary Category”

  1. Armin Avatar

    Thank you, this was exactly what I was looking for.
    Armin

  2. tzs007 Avatar
    tzs007

    Hello!
    You have made a little mistake in your code:

    $wpseo_primary_term = new WPSEO_Primary_Term( ‘category’, get_the_id( $post ) );

    It will be return with false, because you previously get the post ID, so you don’t need to pass it to get_the_id()…

    This is the correct code:

    $wpseo_primary_term = new WPSEO_Primary_Term( ‘category’, $post );

    Cheers

    1. tanner Avatar
      tanner

      Ahh, great catch! I’ve updated the code.

      Thanks

  3. Matt Olpinski Avatar

    Hey Tanner! Thanks so much for this. Super newbie question here: can you post an example of how to use/call the function with example parameters? I’ve spent a lot of time looking for answers and this one looks perfect, except I don’t know exactly how to call the function properly. Thanks

    1. Tanner Avatar
      Tanner

      Matt,

      Glad I was able to help!

      I just added some documentation to the gist that should provide some examples of how to use it in a theme.

  4. Sumit Avatar
    Sumit

    Hello , Can you let me know how to get primary category of woocoomerce products..
    I want to display primary category in products page meta title.

    Thanks

  5. Dante Avatar
    Dante

    This did not work for me, the get_primary_term() method from the instance of WPSEO’s class kept returning false

    Turns out I was passing the post object, and not the post ID, by doing
    $wpseo_primary_term = new WPSEO_Primary_Term( $taxonomy, $post->ID );
    It worked.

    1. dave Avatar
      dave

      Just posting to say thanks all, this worked, but i needed to make the amend Dante suggested.

  6. PlayStation Fanatic Avatar
    PlayStation Fanatic

    Hey, I have been trying to figure out how to show the primary category in my theme for ages. I just found your post and it works like a charm. Thank you very much.

    1. Tanner Avatar
      Tanner

      I’m glad you found what you were looking for

  7. Jim Avatar
    Jim

    Hi. Silly question but where do we put this? Functions.php?

    1. Tanner Avatar
      Tanner

      Hey Jim,

      Yes, you would add the function to your functions.php file and then you could call it within your theme:

  8. Kevin Minderhout Avatar
    Kevin Minderhout

    Thanks for the snippet. If you’re using Woocommerce and have variable products you’ll need to get the information from the parent product. I added the following:

    $type = get_post_type($post);

    if( $type === 'product_variation'){
    $product = wc_get_product($post);
    $post = $product->get_parent_id();
    }

    Don’t forget to use the taxonomy of ‘product_cat’.

  9. Peter Larsen Avatar

    Yes! I just added it to my edd store.
    I’m using the edd related posts plugin and it was showing all the categories a product was in. I added this code and it now only displays the primary category. This is amazing.

    Thanks Tanner 🙂

    1. Tanner Avatar
      Tanner

      Awesome! Glad it helped you out 🤘🏼

  10. James Avatar
    James

    I have posts which are assigned to multiple categories and have used Yoast to select a Primary Category for each one, and your code above to successfully show the primary category in my breadcrumb structure on each page, calling it using the example in your gist.

    I’ve since started to add sub-categories, assigning a few posts to them and for those I’ve then changed the Primary Category to be the sub-category rather than the parent. In Yoast’s breadcrumb schema for each page, it shows up correctly as:

    Home > Parent Category > Sub Category (Primary Category) > Post

    How would I go about adding the Parent Category (i.e. parent of the sub/primary category) into my theme code to show it as part of the breadcrumbs on each page when applicable?

    Thanks!

  11. mheamhea Avatar
    mheamhea

    What would the code look like if I would like woocommerce to use the primary category in product breadcrumbs and URL’s?

  12. Clients Meyne Avatar
    Clients Meyne

    I was using different code to do the same thing. It stopped working and I couldn’t find the problem so I tried this code, and unfortunately it just returns “Array” in place of the categories. Apparently Yoast changed something? Any ideas? Thanks!

    1. adrianovarlotta Avatar

      Not working to me as well 🙁
      Already put code inside functions and insert $post_category = get_primary_taxonomy_term(); on the loop and call echo $primary_category[‘title’]; inside the loop. Without success

  13. adrianovarlotta Avatar

    I found a solution, now you can just insert :
    echo yoast_get_primary_term();
    on your loop, wihout need to put any code on functions.

  14. Bryan Cady Avatar

    @adrianovarlotta Thanks!!! That code worked great

  15. Juegos.Games Avatar

    I am using Yoast at my website and I want to know in the dashboard of WordPress, with a single view of all listing, which is the selected category by Yoast, how can I do it? By example, I have this post https://juegos.games/juego/go-robots/ without main category, and I need to select one category for each post.