# Warn When a Post Title Is Already Used

> Shows a warning in the block editor when another post or page already has the same title, so you avoid confusing duplicates in search results, menus and your own lists.

- Type: PHP
- Runs: Run everywhere
- Category: [Content](https://wpide.com/library/category/content/)
- Tags: block-editor, titles, editorial
- Author: WPIDE Team
- Installs: 0
- Updated: 2026-10-28
- Page: https://wpide.com/library/content-duplicate-title-warning/

## Code

```php
add_action( 'rest_api_init', function () {
    register_rest_route( 'site/v1', '/title-check', array(
        'methods'             => WP_REST_Server::READABLE,
        'permission_callback' => function () {
            return current_user_can( 'edit_posts' );
        },
        'args'                => array(
            'title'   => array( 'type' => 'string', 'required' => true, 'sanitize_callback' => 'sanitize_text_field' ),
            'exclude' => array( 'type' => 'integer', 'default' => 0 ),
            'type'    => array( 'type' => 'string', 'default' => 'post', 'sanitize_callback' => 'sanitize_key' ),
        ),
        'callback'            => function ( WP_REST_Request $request ) {
            global $wpdb;
            $title = trim( $request['title'] );
            if ( mb_strlen( $title ) < 3 ) {
                return rest_ensure_response( array() );
            }
            $rows = $wpdb->get_results( $wpdb->prepare(
                "SELECT ID, post_status FROM {$wpdb->posts} WHERE post_title = %s AND post_type = %s AND ID <> %d AND post_status IN ('publish','future','draft','pending','private') LIMIT 5",
                $title,
                $request['type'],
                (int) $request['exclude']
            ) );
            return rest_ensure_response( array_map( function ( $row ) {
                return array( 'id' => (int) $row->ID, 'status' => $row->post_status, 'edit' => get_edit_post_link( $row->ID, 'raw' ) );
            }, $rows ) );
        },
    ) );
} );

add_action( 'enqueue_block_editor_assets', function () {
    $screen = get_current_screen();
    if ( ! $screen || 'post' !== $screen->base ) {
        return;
    }

    wp_register_script( 'wpide-title-check', false, array( 'wp-data', 'wp-api-fetch', 'wp-url', 'wp-notices', 'wp-dom-ready', 'wp-editor' ), '1.0', true );
    wp_enqueue_script( 'wpide-title-check' );
    wp_add_inline_script( 'wpide-title-check', <<<'JS'
wp.domReady( function () {
    var lastTitle = null, timer = null;
    wp.data.subscribe( function () {
        var editor = wp.data.select( 'core/editor' );
        if ( ! editor || ! editor.getCurrentPostId() ) { return; }
        var title = ( editor.getEditedPostAttribute( 'title' ) || '' ).trim();
        if ( title === lastTitle ) { return; }
        lastTitle = title;
        clearTimeout( timer );
        timer = setTimeout( function () {
            var notices = wp.data.dispatch( 'core/notices' );
            notices.removeNotice( 'wpide-duplicate-title' );
            if ( title.length < 3 ) { return; }
            wp.apiFetch( { path: wp.url.addQueryArgs( '/site/v1/title-check', { title: title, exclude: editor.getCurrentPostId(), type: editor.getCurrentPostType() } ) } ).then( function ( matches ) {
                if ( matches.length ) {
                    notices.createWarningNotice( 'Another item already uses this title (' + matches.map( function ( m ) { return '#' + m.id + ' ' + m.status; } ).join( ', ' ) + ').', { id: 'wpide-duplicate-title', isDismissible: true } );
                }
            } ).catch( function () {} );
        }, 800 );
    } );
} );
JS
    );
} );
```

## Notes

The check runs a moment after you stop typing and looks at published, scheduled and draft items of the same type.

## How to use it

Install the free WPIDE plugin (https://wordpress.org/plugins/wpide/), find "Warn When a Post Title Is Already Used" in its snippet library and add it in one click; or create a new PHP snippet in WPIDE (or any code snippets plugin) and paste the code above. More snippets: https://wpide.com/library/
