Action init fires after WordPress finishes loading, before headers are sent: the standard place to register post types, taxonomies, and rewrites. The current user is already authenticated at this point; hook wp_loaded instead if you need every init callback to have run first.
Fires after WordPress has finished loading but before any headers are sent.
Every example is editable and runs in a real WordPress booted in your browser by WordPress Playground. Press Run, then edit the code: clicking away re-runs it. Nothing is sent anywhere until you do.
Register post types and taxonomies on init so they exist on every request before queries and rewrite matching run.
add_action( 'init', 'myplugin_register_book_post_type' );
function myplugin_register_book_post_type() {
register_post_type(
'book',
array(
'labels' => array(
'name' => __( 'Books', 'myplugin' ),
'singular_name' => __( 'Book', 'myplugin' ),
),
'public' => true,
'has_archive' => true,
'show_in_rest' => true,
'supports' => array( 'title', 'editor', 'thumbnail' ),
)
);
}After adding a post type, flush permalinks once (re-save Settings > Permalinks, or flush_rewrite_rules() in an activation hook), otherwise its archive and single URLs 404. Never flush on every init run; it is expensive.
wp-settings.php:742file scope * themselves on it for all sorts of reasons (e.g. they need a user, a taxonomy, etc.). * * If you wish to plug an action once WP is loaded, use the {@see 'wp_loaded'} hook below. * * @since 1.5.0 */do_action( 'init' ); // Check site status.if ( is_multisite() ) { $file = ms_site_check(); if ( true !== $file ) { require $file;Introduced in 1.5.0. Unchanged from 6.7.7 through 7.1.0.
Signature, return type and hooks compared across 5 parsed releases.