Your code worked absolutely fine for me, so I suspected you forgot to flush the rewrite rules.
Each time after you added code which alters the WordPress rewrite rules, e.g. add_rewrite_rule()
or code which registers/un-registers a CPT or custom taxonomy with URL rewriting enabled, you should always flush the rewrite rules which means WordPress will empty/reset the saved rewrite rules (in the database and .htaccess
file) and regenerate (and re-save) them which would include your newly added or updated rewrite rules.
How to flush the rewrite rules: Just visit the Settings → Permalink Settings page. And there’s no need to click on the “Save Changes” button.
There’s also a programmatic way (see flush_rewrite_rules()
), but in general, the above trick is the preferred way unless you are writing a plugin where you would for example, call the function during the plugin activation and deactivation.