How much control do we have over CPT rewrite slugs? Can I create a “root” page for my CPT with out the page path, and then have paths for other pages?

The way I see it, you could do:

// Via the init hook, do all these:

register_post_type( 'library-books', [
    'public'      => true,
    'label'       => 'Library Books',
    'rewrite'     => [ 'with_front' => false, 'slug' => 'library/books' ],
    'has_archive' => 'library/books',
    // other args here
] );

register_post_type( 'library', [
    'public'      => true,
    'label'       => 'Libraries',
    'rewrite'     => [ 'with_front' => false, 'slug' => 'library' ],
    'has_archive' => false,
    // other args here
] );

add_rewrite_rule( '^library/?$', 'index.php?library=home', 'top' );

I.e.

  • Register the library-books CPT first, with library/books as the rewrite slug as well as has_archive.

  • Then register the library CPT with library as the rewrite slug, and has_archive set to false.

  • And register a custom rewrite rule for the example.com/library which (internally) loads example.com/library/home (which is a post of the library CPT, although you can really modify the rewrite rule’s query to load a post of a different post type such as page).

But of course, in your library CPT, you shouldn’t have a post with books as the slug.