Trusted WordPress tutorials, when you need them most.
Beginner’s Guide to WordPress
WPB Cup
25 Million+
Websites using our plugins
16+
Years of WordPress experience
3000+
WordPress tutorials
by experts

How to Create Custom Post Types in WordPress

Custom post types allow you to go beyond standard posts and pages. They let you create diverse content types tailored to your site’s specific needs.

For example, custom post types let you transform your WordPress site from a simple blogging platform into a robust content management system (CMS).

That’s why we use some custom post types across our own websites. In in this guide, we will show you how to easily create custom post types in WordPress.

How to Create Custom Post Types in WordPress

What Is a Custom Post Type in WordPress?

On your WordPress website, post types are used to help distinguish between different content types in WordPress. Posts and pages are both post types but are made to serve different purposes.

By default, WordPress comes with a few different post types:

  • Post
  • Page
  • Attachment
  • Revision
  • Nav Menu

That said, you can create your own post types, known as custom post types. These are useful when creating content with a different format than a standard post or page.

Let’s say you run a movie review website. Then, you would probably want to create a ‘movie reviews’ post type. You could also create custom post types for portfolios, testimonials, products, and more.

Moreover, custom post types can have different custom fields and their own custom category structure.

On WPBeginner, for example, we use custom post types for our Deals and Glossary sections to keep them separate from our daily blog articles. It helps us better organize our website content.

Many popular WordPress plugins use custom post types to store data on your WordPress website. The following are a few top plugins that use custom post types:

  • WooCommerce adds a ‘product’ post type to your online store
  • WPForms creates a ‘wpforms’ post type to store all your forms
  • MemberPress adds a ‘memberpressproduct’ custom post type

Video Tutorial

Subscribe to WPBeginner

If you’d prefer written instructions, just keep reading.

Do I Need to Create Custom Post Types?

Before you start creating custom post types on your WordPress site, it’s important to evaluate your needs. Often, you can achieve the same results with a normal post or page.

If you are not sure whether your site needs custom post types, then refer to our guide on when you need a custom post type or taxonomy in WordPress.

With that in mind, let’s take a look at how to easily create custom post types in WordPress for your own use. We’ll show you two methods and also cover some ways to display custom post types on your WordPress website:

Ready? Let’s get started.

Creating a Custom Post Type Manually Using WPCode

Creating a custom post type requires you to add code to your theme’s functions.php file. However, we don’t recommend this to anyone but advanced users because even a slight mistake can break your site. Also, if you update your theme, then the code will be erased.

Instead, we will be using WPCode, the easiest and safest way for anyone to add custom code to your WordPress website.

With WPCode, you can add custom snippets and activate a lot of features from its built-in, pre-configured code library. In other words, it can replace many dedicated or single-use plugins you may have installed.

First, you will need to install and activate the free WPCode plugin. For detailed instructions, check out our step-by-step guide on how to install a WordPress plugin.

Once activated, navigate to Code Snippets » Add Snippet from your WordPress dashboard. Then, you’ll want to hover your mouse over ‘Add Your Custom Code (New Snippet)’ and then click ‘Use Snippet.’

Add custom code in WPCode with new snippet

This will open the ‘Create Custom Snippet’ screen.

Now, you can create the code snippet title and toggle the switch to ‘Active.’

Creating a custom code snippet using WPCode

After that, simply paste the following code into the ‘Code Preview’ area. This code creates a basic custom post type called ‘Movies’ that will appear in your admin sidebar and work with any theme.

// Our custom post type function
function create_posttype() {
 
    register_post_type( 'movies',
    // CPT Options
        array(
            'labels' => array(
                'name' => __( 'Movies' ),
                'singular_name' => __( 'Movie' )
            ),
            'public' => true,
            'has_archive' => true,
            'rewrite' => array('slug' => 'movies'),
            'show_in_rest' => true,
 
        )
    );
}
// Hooking up our function to theme setup
add_action( 'init', 'create_posttype' );

If you just want a basic custom post type, then just replace the movies and Movies with your own CPT slug and name and click the ‘Update’ button.

However, if you want even more options for your custom post type, you should use the following code instead of the one above.

The code below adds many more options to the ‘Movies’ custom post type, such as support for revisions, featured images, and custom fields, as well as associating the custom post type with a custom taxonomy called ‘genres.’

Note: Do not combine these two snippets, or WordPress will give you an error because both snippets register the same custom post type. We recommend creating a whole new snippet using WPCode for each additional post type you want to register.

/*
* Creating a function to create our CPT
*/
 
function custom_post_type() {
 
// Set UI labels for Custom Post Type
    $labels = array(
        'name'                => _x( 'Movies', 'Post Type General Name', 'twentytwentyone' ),
        'singular_name'       => _x( 'Movie', 'Post Type Singular Name', 'twentytwentyone' ),
        'menu_name'           => __( 'Movies', 'twentytwentyone' ),
        'parent_item_colon'   => __( 'Parent Movie', 'twentytwentyone' ),
        'all_items'           => __( 'All Movies', 'twentytwentyone' ),
        'view_item'           => __( 'View Movie', 'twentytwentyone' ),
        'add_new_item'        => __( 'Add New Movie', 'twentytwentyone' ),
        'add_new'             => __( 'Add New', 'twentytwentyone' ),
        'edit_item'           => __( 'Edit Movie', 'twentytwentyone' ),
        'update_item'         => __( 'Update Movie', 'twentytwentyone' ),
        'search_items'        => __( 'Search Movie', 'twentytwentyone' ),
        'not_found'           => __( 'Not Found', 'twentytwentyone' ),
        'not_found_in_trash'  => __( 'Not found in Trash', 'twentytwentyone' ),
    );
     
// Set other options for Custom Post Type
     
    $args = array(
        'label'               => __( 'movies', 'twentytwentyone' ),
        'description'         => __( 'Movie news and reviews', 'twentytwentyone' ),
        'labels'              => $labels,
        // Features this CPT supports in Post Editor
        'supports'            => array( 'title', 'editor', 'excerpt', 'author', 'thumbnail', 'comments', 'revisions', 'custom-fields', ),
        // You can associate this CPT with a taxonomy or custom taxonomy. 
        'taxonomies'          => array( 'genres' ),
        /* A hierarchical CPT is like Pages and can have
        * Parent and child items. A non-hierarchical CPT
        * is like Posts.
        */ 
        'hierarchical'        => false,
        'public'              => true,
        'show_ui'             => true,
        'show_in_menu'        => true,
        'show_in_nav_menus'   => true,
        'show_in_admin_bar'   => true,
        'menu_position'       => 5,
        'can_export'          => true,
        'has_archive'         => true,
        'exclude_from_search' => false,
        'publicly_queryable'  => true,
        'capability_type'     => 'post',
        'show_in_rest' => true,
 
    );
     
    // Registering your Custom Post Type
    register_post_type( 'movies', $args );
 
}
 
/* Hook into the 'init' action so that the function
* Containing our post type registration is not 
* unnecessarily executed. 
*/
 
add_action( 'init', 'custom_post_type', 0 );

You may notice the part where we have set the hierarchical value to false. If you would like your custom post type to behave like pages rather than posts, then you can set this value to true.

Another thing to notice is the repeated usage of the twentytwentyone string, this is called the ‘Text Domain.’ If your theme is translation-ready and you want your custom post types to be translated, then you will need to mention the text domain used by your theme.

You can find your theme’s text domain inside style.css file in your theme directory or by going to Appearance » Theme File Editor in your admin panel. The text domain will be mentioned in the header of the file.

Finding the textdomain for a theme

Simply replace twentytwentyone with your own theme’s ‘Text Domain.’

Once you’re happy with the changes, simply click the ‘Update’ button, and WPCode will handle the rest.

Creating a Custom Post Type With a Plugin

Another easy way to create a custom post type in WordPress is by using a plugin. This method is recommended for beginners because it is safe and super easy.

The first thing you need to do is install and activate the Custom Post Type UI plugin. For more details, see our step-by-step guide on how to install a WordPress plugin.

Upon activation, you need to go to CPT UI » Add / Edit Post Types to create a new custom post type. You should be on the ‘Add New Post Type’ tab.

Create a New Custom Post Type With a Plugin

In this area, you’ll need to provide a slug for your custom post type, such as ‘movies.’ This slug will be used in the URL and in WordPress queries, so it can only contain letters and numbers.

Below the slug field, you need to provide the plural and singular names for your custom post type.

If you like, you can click on the link that says, ‘Populate additional labels based on chosen labels.’ This will automatically fill in the additional label fields down below and will usually save you time.

You can now scroll down to the ‘Additional Labels’ section. If you didn’t click the link we mentioned, you will need to provide a description for your post type and change labels.

Scroll Down to the Additional Labels Section

These labels will be used throughout the WordPress user interface when you are managing content in that particular post type.

Next comes the post type settings. From here, you can set up different attributes for your post type. Each option comes with a brief description explaining what it does.

Scroll Down to the Post Type Settings Section

For instance, you can choose not to make a post type hierarchical like pages or sort chronological posts in reverse.

Below the general settings, you will see the option to select which editing features this post type would support. Simply check the options that you want to be included.

Check the Supports Options You Want to Include

Finally, click on the ‘Add Post Type’ button to save and create your custom post type.

That’s all, you have successfully created your custom post type! You can now go ahead and start adding content.

Displaying Custom Post Types on Your Site

WordPress comes with built-in support for displaying your custom post types. Once you have added a few items to your new custom post type, it’s time to display them on your website.

There are a few methods that you can use, and each one has its own benefits.

Displaying Custom Post Types Using Default Archive Template

First, you can simply go to Appearance » Menus and add a custom link to your menu. This custom link is the link to your custom post type.

Add a Custom Link to Your Menu

If you are using SEO-friendly permalinks, then your custom post type’s URL will most likely be something like this:

http://example.com/movies

If you are not using SEO-friendly permalinks, then your custom post type URL will be something like this:

http://example.com/?post_type=movies

Don’t forget to replace ‘example.com’ with your own domain name and ‘movies’ with your custom post type name.

You can then save your menu and visit the front end of your website. You will see the new menu item you added, and when you click on it, it will display your custom post type’s archive page using the archive.php template file in your theme.

Preview of Custom Post Type Menu Item

Creating Custom Post Type Templates

If you don’t like the appearance of the archive page for your custom post type, then you can use a dedicated template for custom post type archives.

All you need to do is create a new file in your theme directory and name it archive-movies.php. Make sure you replace ‘movies’ with the name of your custom post type.

To get started, you can copy the contents of your theme’s archive.php file into the archive-movies.php template and then modify it to meet your needs.

Now, whenever the archive page for your custom post type is accessed, this template will be used to display it.

Similarly, you can create a custom template for the single-entry display of your post type. To do that you need to create single-movies.php in your theme directory. Don’t forget to replace ‘movies’ with the name of your custom post type.

You can get started by copying the contents of your theme’s single.php template into the single-movies.php template and then modifying it to meet your needs.

To learn more, see our guide on how to create custom single post templates in WordPress.

Displaying Custom Post Types on The Front Page

One advantage of using custom post types is that they keep your custom content types separate from your regular posts. However, you can display custom post types on your website’s front page if you like.

Simply add this code as a new snippet using the free WPCode plugin. Please see the section of this article on manually adding code for detailed instructions.

add_action( 'pre_get_posts', 'add_my_post_types_to_query' );
 
function add_my_post_types_to_query( $query ) {
    if ( is_home() && $query->is_main_query() )
        $query->set( 'post_type', array( 'post', 'movies' ) );
    return $query;
}

Don’t forget to replace ‘movies’ with your custom post type.

Querying Custom Post Types

If you are familiar with coding and would like to run loop queries in your templates, then here is how to do that. By querying the database, you can retrieve items from a custom post type.

You will need to copy the following code snippet into the template where you wish to display the custom post type.

<?php 
$args = array( 'post_type' => 'movies', 'posts_per_page' => 10 );
$the_query = new WP_Query( $args ); 
?>
<?php if ( $the_query->have_posts() ) : ?>
<?php while ( $the_query->have_posts() ) : $the_query->the_post(); ?>
<h2><?php the_title(); ?></h2>
<div class="entry-content">
<?php the_content(); ?> 
</div>
<?php endwhile;
wp_reset_postdata(); ?>
<?php else:  ?>
<p><?php _e( 'Sorry, no posts matched your criteria.' ); ?></p>
<?php endif; ?>

This code defines the post type and number of posts per page in the arguments for our new WP_Query class. It then runs the query, retrieves the posts, and displays them inside the loop.

Displaying Custom Post Types in Widgets

You will notice that WordPress has a default widget to display recent posts, but it does not allow you to choose a custom post type.

What if you wanted to display the latest entries from your newly created post type in a widget? Luckily, there is an easy way to do this.

The first thing you need to do is install and activate the Custom Post Type Widgets plugin. For more details, see our step-by-step guide on how to install a WordPress plugin.

Upon activation, simply go to Appearance » Widgets and drag and drop the ‘Recent Posts (Custom Post Type)’ widget to a sidebar.

Recent Custom Post Type Widget

This widget allows you to show recent posts from any post type. You need to select your custom post type from the ‘Post Type’ dropdown and select the options you want.

After that, make sure you click the ‘Update’ button at the top of the screen and then visit your website to see the widget in action.

Preview of Recent Custom Post Type Widget

The plugin also provides custom post type widgets that display archives, a calendar, categories, recent comments, search, and a tag cloud.

So, feel free to explore and choose the one you need.

Custom Post Type Archives Widget

We hope this tutorial helped you learn how to create custom post types in WordPress. Next, you may also want to learn how to create a custom archive page in WordPress or check out our list of important pages that every WordPress blog should have.

If you liked this article, then please subscribe to our YouTube Channel for WordPress video tutorials. You can also find us on Twitter and Facebook.

Disclosure: Our content is reader-supported. This means if you click on some of our links, then we may earn a commission. See how WPBeginner is funded, why it matters, and how you can support us. Here's our editorial process.

Editorial Staff

Editorial Staff at WPBeginner is a team of WordPress experts led by Syed Balkhi with over 16 years of experience in WordPress, Web Hosting, eCommerce, SEO, and Marketing. Started in 2009, WPBeginner is now the largest free WordPress resource site in the industry and is often referred to as the Wikipedia for WordPress.

The Ultimate WordPress Toolkit

Get FREE access to our toolkit - a collection of WordPress related products and resources that every professional should have!

Reader Interactions

134 CommentsLeave a Reply

  1. Sarah Chant

    Hi there, what plugin did you use to organise your deals on your deals page (mentioned above) please? It looks fantastic!

    • WPBeginner Support

      For the time being they are styled based on our custom theme and not a specific plugin.

      Admin

  2. Aurora

    Ah I would need to re-read this again since my brain isn’t primed for coding at the moment lol

    • WPBeginner Support

      Our article will be here for when you are ready :)

      Admin

  3. Anna

    Good stuff! TY!

    Is it possible to select a category for the CPT or create it’s own category list?
    In your example of ‘Movies’ – select which category – Family, Drama, Action, etc?

  4. Michelle

    Hi! How can I set the query to only display custom post types by category on the category page? Currently, my query pulls ALL the post type, and I can’t seem to get just current category to display. thanks

  5. hussain

    I have used this method which you explained above, but after creating a new menu, menu has created successfully created but when I click my menu it shows me error that “This page could not foun”

    • WPBeginner Support

      It sounds like you would need to check and resave your permalinks to be safe. The other thing you could do would be to ensure you have a custom post type published for be found on the page.

      Admin

  6. Jarkko

    So I used Code Snippets and the longer code but the features after ‘supports’ are not visible anywhere? Shouldn’t they be visible when clicking “Add new”… How do I insert a new movie and the information of it… I don’t get it.

    • WPBeginner Support

      There should be a new section in your admin area where you can add new posts of your custom post type similar to how you add posts or pages.

      Admin

  7. Hafeez Ulllah

    How cn display custom post type and where the code of display will be pasted

  8. Johan

    Seems to work perfectly, except for one thing: My theme is showing featured images on the pages. But when I use the CPT the images are never show, whatever I do. Any idea why?

    • WPBeginner Support

      Your theme likely has a different template being used, if you reach out to your theme’s support they should be able to assist.

      Admin

  9. D Hebing

    I tried many things with the code above, even compare it with the twintytwintyone theme of wordpress. But the post types don’t appear in the backend in the post editor.

  10. Aurelien

    5 years on, still useful! Thank you guys

    • WPBeginner Support

      Glad you’ve found our content helpful :)

      Admin

  11. Max

    Thanks very useful.

    What do you think? In such cases from view of site speed it is better to install the plugin or write the code you provide?

    • WPBeginner Support

      There shouldn’t be a difference in speed with either method being used.

      Admin

  12. Marshal Tudu

    Thanks a lot for the help. I am trying to create a movie database on my website
    Your post really helped me.

    • WPBeginner Support

      Glad our guide was helpful :)

      Admin

  13. Harsha

    How to migrate old posts to the new post type?

  14. Leslie Campos

    Great article! I tried to add two different post types on top of blog posts but the second add_action( ‘init’, ‘create_posttype’ ); overwrote the first one. I don’t know php but am wondering if it is possible to create two different ones in the same functions.php file. I don’t know php so perhaps it’s the way I am writing it?

    • WPBeginner Support

      We would recommend using the plugin method to make the process easier. For a second post type with the code, you would need to copy from lines 4 to 17 and paste it on a new line below 17 then rename movies to a different name.

      Admin

  15. Girish Sahu

    Really loved the article, Simple explained and was really of great help.
    I wanted to mix custom posts and blogs post in a single page and was able to do so after reading the article.

    • WPBeginner Support

      Glad our guide was helpful :)

      Admin

  16. Rafiozoo

    Great recipe! Thank you!
    One question:
    ‘exclude_from_search’ => true
    should exclude my new custom posts from search results, I believe. Why does not work?

  17. snelson

    Is there a way to display the new post type without the new slug? example. Default is mysite.com/newposttype/newpage

    I would like

    mysite.com/newpage/

  18. Yogesh

    Hi,

    I tried to use the manual approach using the simple code youve mentioned for creating a custom post type, but unfortunatley the posts dont show up (page not found error). The post permalink structure looks fine but the posts dont get displayed.

    • WPBeginner Support

      You may want to clear the cache for your site and resave your permalinks to clear that issue.

      Admin

  19. rajni

    hey thank you so much it working fine but i want to show post type on a page where only categories will show and when click on category post listed under this category will open can you please suggest me how to do that.thank you in advance

    • WPBeginner Support

      For what it sounds like you’re wanting, you would want to ensure that categories are enabled for your custom post type and you could then add the category link in your menu for the page listing them how you want

      Admin

  20. G'will Chijioke

    Hi, i am a newbie developer trying to create a custom post type.

    All is good, just 1 huge problem.

    I want to display the taxonomies that i created and linked to the post (tags and categories ) on the post itself.

    i want to show it on my breadcrumbs as well.

    pls it would mean d world if you helped me out.

    Thanks in advance.

  21. rana ritesh singh

    nice post

    • WPBeginner Support

      Thank you :)

      Admin

  22. Haibatan

    I want a CPT for my english posts, my site is in an RTL language, is it possible?

  23. RZKY

    One question, in the default WP post dashboard, there’s a filter by categories feature on top of the list.

    So I already link my custom post type with a custom taxonomy, but the filter menu is not showing (A portfolio post type, and the portfolio category custom taxonomy). Is there any settings i need to enable? I’m doing this from inside my functions.php

  24. Feras

    Hi there, So “Custome post type UI” is not compatible with my wp version! is there any useful plugin that I CAN USE

  25. Oscar

    Hi!. I want to ask you something.
    I created a Custom Post Types.
    But when i create a post, there isnt the options “Page Attributes”, to choose the template and order the posts.
    How can I get it?

    Thanks in advanced.

    • Syed Furqan Ali

      Hi Oscar,

      If you are using the CPT UI plugin to create custom post types, you’ll need to ensure that you enable the “Page Attributes” option under the “Supports” section. This will allow you to assign parent pages to your custom post types. Similarly, if you are using custom code to create custom post types, make sure to include the “page-attributes” in the supports parameter to enable this feature.

  26. vinay

    post is created but custom fields are not showing why?/

  27. Kevin

    I’ve created a CPT with unique archive page, but I would like to be able to show a featured image for the archive page (not from the first post) but as the archive page doesn’t exist in “pages” there is no way to add the featured image

    how would this be achieved ?

  28. Juno

    Is it possible to access these custom post types via WP REST API? If so how? (for GET, POST, etc.

  29. Mottaqi

    I want a custom post type page that will be open from archive.php page with all it’s posts and under this page I want to place it’s all posts as sub menu items. But when I create a custom link page and place it’s sub menu items as I describe, sum menu url will open but my main archive page , I mean that post type page url will disappear.
    Plz I want to access both pages.. But how…?

  30. Steven Denger

    Will adding Custom Post Types allow me to have another posting page for these? My regular Home page has products running through that. I need an additonal posting page for product reviews. When I create a review, I need it to post on another feature page. Is this what tis is for?

  31. utkarsh

    nevermind that last question i asked read your whole article and got it

  32. utkarsh

    Hey what does ‘twentythirteen’ in
    “_x(‘Movies’, ‘Post Type General Name’, ‘twentythirteen’)”

    • Jim

      Also notice repeated usage of twentythirteen, this is called text domain. If your theme is translation ready and you want your custom post types to be translated, then you will need to mention text domain used by your theme. You can find your theme’s text domain inside style.css file in your theme directory. Text domain will be mentioned in the header of the file.

  33. Angela

    Hello and thank you for this post (and several others).

    I have created the new custom post type of “stories” and its showing up in my WP dashboard. I can create a new post but when I try to open the Beaver Builder page builder to build the post, it won’t open and goes to “Sorry, this page doesn’t exist” error page.

    Can you help?

    Thank you,
    Angela

    • WPBeginner Support

      Hi Angela,

      First, you should try updating your permalinks. Simply visit Settings » Permalinks and then click on the save changes button without changing anything.

      If this doesn’t resolve your issue, then contact plugin’s support.

      Admin

      • Angela

        Hi and thank you for your reply. I did what you suggested and it didn’t help. My plugin is created using the customer post type code above and is placed in a site-specific plugin, so I have no plugin support source from which to seek help other than you :)

        I deleted the site-specific plugin (which of course included the CPT code) and new posts and pages still won’t load using the Beaver Builder theme page builder function, but they will at least show the page with a large white bar loading endlessly. I deactivated Ultimate Add-ons for Beaver Builder plugin and new posts and pages will now load using page builder. I think there may have been a conflict between UABB plugin and the CPT plugin and now the conflict remains in UABB plugin.

        Any suggestions would be much appreciated. I also have put in a request to UABB. Maybe between the two of you, you could help resolve this issue and make note of this conflict for future reference.

  34. JonO

    Great site BTW, really really helpful so thanks for creating.

    I’m super stuck and have been reading tutorials all over the web and not found the answers I need.

    I want to create a user opt-in custom taxonomy (Let’s call it user_interests) that can be used to display a custom list of posts that are unique to that particular user.

    User will opt-in to user_interest tags/catergories/whatever during sign up or when editing profile.

    Then the WP loop should include these values to display posts

    Any ideas, help would be really appreciated, thanks.

  35. Jonathan

    How do I get my user/visitors to my site be able to enter information to a form, and have that submitted data be displayed on which ever page or location I like? I want to allow my users be able to submit complaints and have other users able to like/reply to the main complaint submitted.

    Am I able to do this with Custom Post Type?

Leave A Reply

Thanks for choosing to leave a comment. Please keep in mind that all comments are moderated according to our comment policy, and your email address will NOT be published. Please Do NOT use keywords in the name field. Let's have a personal and meaningful conversation.