But when I try
example.com/lessonI get page not found error.
Like I pointed in my comment to your question, that’s actually how it works, where the term slug needs to be specified in the URL. That’s why example.com/lesson/english (term slug is english) and example.com/lesson/french (term slug is french) work, but not example.com/lesson (term slug not specified).
So one way to make example.com/lesson works, is by setting the has_archive parameter to lesson when registering the CPT memory-cards via register_post_type(). For example:
register_post_type( 'memory-cards', array(
'labels' => array(
'name' => 'Memory Cards',
'singular_name' => 'Memory Card',
),
'public' => true,
'has_archive' => 'lesson',
) );
But that also means, example.com/memory-cards, which is the default archive URL for your memory-cards CPT (when has_archive is set to true), would no longer display the CPT archive.
To fix that, or to preserve the default archive URL, you can use add_rewrite_rule() to add the rewrite rules for example.com/lesson, like so:
register_taxonomy( 'lesson', 'memory-cards', array(
'labels' => array(
'name' => 'Lessons',
'singular_name' => 'Lesson',
),
'rewrite' => true,
// ...other args here...
) );
add_rewrite_rule( 'lesson/?$', 'index.php?post_type=memory-cards', 'top' );
add_rewrite_rule( 'lesson/page/(\d+)/?$', 'index.php?post_type=memory-cards&paged=$matches[1]', 'top' );
The second rewrite rule will handle paged requests such as example.com/lesson/page/2/.