How to Create a Custom Post Type in WordPress (With and Without Plugin)
Last edited on July 3, 2025

WordPress comes with built-in “post” and “page” content types. Custom Post Types (CPTs) let you create entirely new content types for your site โ€“ for example, a Book, Movie, Portfolio, or Testimonials section. As the WordPress documentation explains, the core Post API allows developers to register new post types stored in the database, and WordPress will automatically generate an admin menu and UI to manage them. In other words, once set up, your custom type appears in the dashboard like a normal section (just like Posts and Pages).

Custom Post Types are great for storing data objects other than posts and pages. For beginners, there are two main ways to create a CPT in WordPress: without a plugin (by writing a small bit of code) or with a plugin (Advanced Custom Fields (ACF)). Below, we cover both approaches in detail.

Custom Post Type Without a Plugin

AFC Without Plugin

To create a CPT without a plugin, you add some code to your theme functions.php file or a custom plugin. The key function is register_post_type(), which tells WordPress about the new type. Important steps include:

Hook into init. WordPress documentation warns that post types must be registered during the init action, not too early. In practice, that means you write an init hook. For example, WordPress own docs show code like:

add_action('init', 'my_cpt_init');
function my_cpt_init() {
    register_post_type( /* ... */ );
}
  • ย This ensures the custom type is set up when WordPress initializes.

Define labels and arguments. Inside your function, call register_post_type( $key, $args ). The $key is a short, unique slug (lowercase, no spaces). The $args array defines how the CPT behaves. At minimum, you give it labels (for plural and singular names) and a few settings. For example:

function my_book_post_type() {
    $args = array(
        'labels' => array(
            'name' => 'Books', 
            'singular_name' => 'Book'
        ),
        'public' => true,
        'has_archive' => true,
        'show_in_rest' => true
    );
    register_post_type('book', $args);
}
add_action('init', 'my_book_post_type');
  • In this example, we register a “book” CPT with basic settings. The labels array controls the menu and page titles (“Books” vs “Book”). Other common args include:
    • public โ€“ whether the type is publicly visible (recommended for front-end content). Setting it to true generally makes it appear in the admin menu and archives.
    • has_archive โ€“ enables an archive page (e.g. example.com/book/).
    • show_in_rest โ€“ allows the Gutenberg editor and REST API support (makes the CPT compatible with blocks).
    • supports โ€“ which editor features to include (title, editor, excerpt, thumbnail, etc.). WordPress notes CPTs can support any core feature via the supports argument.
  • Flush permalinks. After registering a CPT (especially on a live site), go to Settings โ†’ Permalinks in the dashboard and click “Save Changes” to rewrite rules. This ensures your new CPT URLs (archives, single items) work without 404 errors. (No additional code is needed if you do this step manually.)

Putting it all together, your code might be:

function my_portfolio_post_type() {
    $args = array(
        'labels' => array(
            'name' => 'Portfolios',
            'singular_name' => 'Portfolio'
        ),
        'public' => true,
        'has_archive' => true,
        'show_in_rest' => true,
        'supports' => array('title', 'editor', 'thumbnail')
    );
    register_post_type('portfolio', $args);
}
add_action('init', 'my_portfolio_post_type');

This code (in a plugin or your theme functions.php) creates a Portfolio section where you can add โ€œportfolioโ€ posts in the admin menu. You can replace ‘portfolio’ and labels with your content type and names. Remember, each CPT key should be unique and under 20 characters (lowercase, underscores/dashes only). For more arguments and details, refer to the WordPress Codex or developer handbook on register_post_type().

Creating a Custom Post Type With the ACF Plugin

advanced custom field Plugin

For beginners who prefer a graphical interface, the Advanced Custom Fields (ACF) plugin (free or Pro) can register custom post types without coding. ACF adds a “Post Types” menu under the Custom Fields (ACF) menu in the WordPress admin. The steps are:

  1. Install and activate ACF. If you haven’t already, install Advanced Custom Fields and activate it. (ACF Pro has additional features, but the basic Post Types screen is available in both versions.)
  2. Go to ACF โ†’ Post Types, click “Add New.” In the WordPress dashboard sidebar under Custom Fields (ACF), find Post Types, then click Add New. This opens a form for creating a new CPT
    Screenshot: ACF’s “Add New Post Type” screen, where you fill in labels and settings without coding.
  3. Enter the basic settings. Fill in the “Plural Label” and “Singular Label” for your content (e.g., “Books” and “Book”), and let ACF generate the Post Type Key (you can edit the key if needed). These fields are required to create the CPT. You can also set Public (whether it’s visible on the site) and Hierarchical (whether items can have parent/child order like pages), which defaults to off.
  4. Configure advanced options (optional). ACF lets you control nearly every CPT argument via checkboxes and fields. By expanding the Advanced Configuration section, you can choose features like:
    • Supports: select if items should have titles, editors, thumbnails, etc. (This is similar to the supports array in code).
    • Linked Taxonomies: attach existing categories or custom taxonomies to this CPT.
    • Visibility settings: decide if the CPT shows in menus, search results, admin bar, etc.
    • URL and archive options: control the slug (rewrite), whether it has an archive page, and RSS feeds.
    • Permissions and REST API: set custom capabilities names, enable REST API support (blocks), etc.
  5. By default, ACF hides most of these extra settings to keep it simple; you can expand the General, Labels, Visibility, URLs, and Permissions sections to tweak them.
  6. Publish the custom post type. After filling in the labels and options, click Publish. The new CPT is now active. You’ll see it listed on the Post Types screen in ACF and in the WordPress admin menu (often under its plural label). ACF also suggests next steps like adding custom fields to the type, but the CPT itself is already created.

Using ACF means no PHP code is needed to register the type. You manage it entirely through the plugin’s interface. The screenshot above illustrates the ACF form; you simply enter names and select options, then save. If you later want to disable or remove the CPT, you can deactivate it in ACF (or delete the field group).

Note: Advanced Custom Fields primarily manages fields, but it includes the Post Types feature for ease of setup. You can think of the ACF CPT screen as a user-friendly front end for register_post_type(). Once you publish, WordPress treats the type just like if you had coded it. For example, you can go to Appearance โ†’ Menus to add the new CPT archive link to a menu, or create theme templates like single-portfolio.php for custom display.

FAQs

A custom post type is a new content type you create in WordPress, different from the built-in “post” or “page.” It lets you store and manage a distinct set of content (like books, portfolios, or products) with its menu and URLs.

Use a CPT when you have content that doesn’t fit the blog-post format. For example, a book review or a movie listing might have special fields and should be grouped separately. CPTs help organize content logically and keep the admin area clean.

Not necessarily. You can use PHP to register a type (using register_post_type). But you can also use plugins like Advanced Custom Fields (ACF) to set up CPTs via the dashboard, with no coding required.

The ACF “Post Types” screen lets you define a new post type in a form: you enter labels (e.g., singular and plural names) and toggle options (public, archive, supported features) in the UI. When you save, ACF creates the type behind the scenes. It saves beginners from writing PHP.

Yes. If you used ACF, you can deactivate or delete the type from the ACF interface. If you coded it, you would remove or adjust the code in your theme/plugin. In either case, WordPress will stop showing that CPT in the admin. Note that existing entries of that type might remain in the database unless you delete them.

Conclusion

In summary, WordPress lets you create custom post types either by writing code or by using a plugin interface:

  • Manual (code) method: Involves using the register_post_type() function inside an init hook. This approach gives you full control and is great for developers. It requires a small snippet of code (usually in functions.php) to define labels, visibility, and features for the new type.
  • Plugin (ACF) method: Uses Advanced Custom Fields’ admin UI to set up the type without touching code. This is beginner-friendly and fast: simply install ACF, fill in the label fields, toggle options, and save. ACF then registers the type for you behind the scenes.

Both methods create identical “custom post types” in WordPress. Which you choose depends on your comfort level: coding gives more flexibility, while ACF provides simplicity. Once created, your custom post type will appear in the admin menu and can be filled with content just like posts or pages. You can then display that content on the front end with templates or shortcodes as needed.

Code What you want to present and organize your content in WordPress can be done with custom post types, whether you want to use code or use ACF. For beginners, using ACF is an easy way to get started without worrying about syntax, while learning the manual method helps you understand how things work under the hood.

About the writer

Hassan Tahir Author

Hassan Tahir wrote this article, drawing on his experience to clarify WordPress concepts and enhance developer understanding. Through his work, he aims to help both beginners and professionals refine their skills and tackle WordPress projects with greater confidence.

Leave a Reply

Your email address will not be published. Required fields are marked *

Lifetime Solutions:

VPS SSD

Lifetime Hosting

Lifetime Dedicated Servers