What is a custom post type?

A custom post type, often shortened to CPT, is any content type added to WordPress beyond the built-in ones. WooCommerce's product is a custom post type, and so are the events, portfolios, testimonials and listings that themes and plugins create. Each gets its own admin menu, URL pattern and, optionally, an archive page.

For SEO, a handful of registration settings decide whether that content is reachable, crawlable and listed in sitemaps.

How one is registered

A post type is declared in code with register_post_type():

php
add_action( 'init', function () {
	register_post_type( 'recipe', array(
		'label'        => 'Recipes',
		'public'       => true,
		'has_archive'  => true,
		'rewrite'      => array( 'slug' => 'recipes', 'with_front' => false ),
		'show_in_rest' => true,
		'supports'     => array( 'title', 'editor', 'thumbnail', 'excerpt' ),
	) );
} );

That produces single recipes at example.com/recipes/lentil-ragu/ and an archive at example.com/recipes/.

ArgumentDefaultEffect
publicfalseWhether the type has front-end URLs at all. Non-public types are for internal data
publicly_queryableSame as publicWhether single items can be requested by URL
exclude_from_searchOpposite of publicWhether items are left out of the site's own search
has_archivefalseWhether an archive page listing all items exists
rewritetrueThe URL slug. Defaults to the post type's name
show_in_restfalseNeeded for the block editor

Note the first default. A type registered without 'public' => true has no public pages, which is right for things like form entries and wrong for content you want to rank.

Common SEO problems with custom post types

  • 404s on every item right after registering. WordPress has not rebuilt its rewrite rules. Visiting Settings → Permalinks and saving fixes it.
  • Public pages nobody intended. Types meant as building blocks, such as testimonials, team members or slider items shown inside other pages, are often registered as public. Each item then has a thin page of its own that gets indexed. Set public to false, or noindex the type.
  • An empty or missing archive. With has_archive on, the archive is a real URL that needs a title, a description and a template worth landing on. With it off, a manually built page has to do the job of listing the items.
  • Slug changes. Renaming rewrite['slug'] changes every URL of the type with no redirect from core.
  • No metadata or schema. A theme's custom template may omit what posts get by default. Check the title, canonical tag and structured data on one item.
  • Slug collisions. A post type slug services and a page with the slug services compete for the same address.

Sitemaps and plugins

The WordPress core sitemap includes every post type registered as public, so a public testimonial type appears there automatically. SEO plugins generally let you decide per type. Hydrogen SEO lists posts, pages, custom post types and taxonomy archives in its XML sitemaps, with switches for each, and applies title and meta templates per post type. Developers can extend its editor panel and analysis to a new type as described in extending Hydrogen SEO.

Choosing between a post type, a category and a page

Make a custom post type when the content has its own fields and its own template, and there will be many items: products with prices, events with dates, properties with addresses. Use a category when the items are ordinary articles that only need grouping. Use plain pages for a handful of one-off items.

Structured content also pairs naturally with structured data. An event type maps to Event schema, a recipe type to Recipe schema, and a job type to JobPosting, with the type's custom fields supplying the property values.

Common questions

Are custom post types good for SEO?

They are neutral. Search engines see ordinary pages. The benefit is organisational: consistent templates, URLs and structured data for one kind of content. Problems arise only from misconfigured visibility or thin item pages.

Why do my custom post type pages return 404?

Usually because the rewrite rules were not refreshed after the type was registered or its slug changed. Open Settings, then Permalinks, and click Save Changes.

Are custom post types included in the WordPress sitemap?

Yes, if they are registered as public. Types registered with public set to false are left out.