WordPress might not be showing your Custom Post Types and Custom Taxonomies on the Menus screen for a really stupid reason

I’m working on a new WordPress site that’s going to have both custom post types and custom taxonomies, and I want my custom taxonomies’ archive pages to be in the site’s navigation menu.

Seems like it should be easy, right? If you set show_in_nav_menus to true in register_post_type() or register_taxonomy(), you’re supposed to get access to add them to your menus.

But when I set that, they still didn’t appear on the Menus screen. What the…?

I found it exceptionally difficult to track down any information about this, although I did eventually find a tutorial on the very subject but… whoa, those are some old screenshots! The tutorial is a decade old.

Nonetheless, I proceeded to try to make it work, with extensive customizations to suit my needs. Strangely — and it should have been a clue to me — they wouldn’t appear if I gave the meta boxes the name of my custom taxonomy, but if I gave them an arbitrary name, it did work. But there were still some quirks, so I started digging around in the inspector to figure out what was what. Then I discovered something really odd.

They were already in the page. Only, they weren’t displaying. That’s because they all had a CSS class hide-if-js applied. So what’s that all about?

Well… it was really stupid. They were “unchecked” under Screen Options. You know, that little tab at the top right of every WordPress admin page.

My best guess here is that it’s because I had already been to the Menus page for this site before I started building the CPTs and taxonomies, so when I added them to the theme, my personal preferences for Screen Options on the Menus page had already been set, and therefore they defaulted to “unchecked.”

That seems kind of stupid. More specifically, it seems stupid that WordPress gives you the option to turn the items in the Add menu items list off. But it definitely should default any new items that suddenly appear, i.e. that are not already “on” or “off” in your preferences, to “on.” So you, like, know they exist.

Things that should be obvious: Fixing a 404 error on Custom Post Type archive pages after converting WordPress to Multisite

Maybe it’s just hard to find because it’s such an edge case. Or is it?

Here’s the scenario: you’re converting an existing WordPress site that uses Custom Post Types (with archive pages) to Multisite.

Suddenly, when you’ve switched the site, your CPT archive pages return a 404 error.

Check this: insert /blog into the URL, like so…

Old URL

http://example.com/my-cpt-archive

New URL

http://example.com/blog/my-cpt-archive

Does it work? If so, good. If not, I can’t help you. *shrug*

Let’s just assume it does work, and continue…

You see, Multisite inserts /blog into the URL to prevent URL conflicts between the different sites. Problem is, it’s kind of stupid about it, especially if your site is not a “blog” (and despite what the core team thinks, I’m pretty sure most WordPress sites these days are not blogs). It doesn’t do anything to change page URLs, which are just as likely to conflict.

Anyway, there are two things you need to do. First, go to Settings > Permalinks. (Note that /blog has appeared in all of the permalink structures!) Switch to “Default”, save, then switch back to whatever you want it to be and save again. (Note that /blog has disappeared!)

This still isn’t going to fix your CPT archives though. For that you need to go into your functions.php file in your theme, or wherever you are registering the CPTs in your theme/plugin. In the register_post_type() function, you may have 'rewrite' defined, like this:

'rewrite' => array('slug' => 'something'),

Change it to this:

'rewrite' => array('with_front' => false, 'slug' => 'something'),

You’ll need to flush the rewrite rules by temporarily adding flush_rewrite_rules(); in the functions.php file, uploading it, loading a page, and then removing the code and re-uploading the file. Or, you can refresh the Settings > Permalinks page. (Much easier, but I haven’t tested to be 100% sure it works in this case.)