Skip to Content
Docs
Routing
WordPress Routing

WordPress Routing

Rather than using file-based routing, we allow WordPress to serve as the ‘authority’ on what a given URL should display.

This results in a tighter coupling between the CMS and the frontend — with a single source of truth for getting/resolving URLs, with very minimal configuration — and allows us to serve the site as both an SPA on the WordPress server (no Node.js needed), as well as a standalone SSR frontend (deployed to Vercel).

The stack essentially allows the Wordpress Template Hierarchy  to unfold as normal, but it allows .tsx files to be used, instead of .php files. So, when WordPress attempts to look for single-event.php, it’ll instead look for views/single-event.tsx.

Custom Routes

Custom routes can be registered using the ED()->addCustomRoute() method in PHP. Read More

Post Type Routing

The code below would provide:

  • a listing page at /work, which would use views/archive-project.tsx as the template.
  • a page for each project at /work/{slug}, which would use views/single-project.tsx as the template.
ED()->registerPostType("projects", [ /* ... */ "has_archive" => true, "rewrite" => [ "slug" => "work", "with_front" => false ] ])

To disable the default listing page, just pass "has_archive" => false
To disable the default post page, just pass "rewrite" => false

Posts URLs without pages

Sometimes you might want to redirect a post type to another page. You can use the post_type_link  filter to do this.

ED()->registerPostType("projects", [ /* ... */ // Disable the default route, to remove it from the router "rewrite" => false ]) // Return a custom URL for this post add_filter('post_type_link', function ($url, $post) { if ($post->post_type === 'job') { return "/jobs?job=".$post->post_name; } return $url; }, 10, 2);

Note that this doesn’t affect how routes are resolved — just how links are generated.

The same functionality can be applied to Taxonomy terms too, via term_link .

Rule Flushing Hack

WordPress caches the routing rules for performance reasons, which can sometimes result in routing updates not applying.

The stack tracks custom route and post-type declarations, and automatically calls flush_rewrite_rules  when changes are detected. If you’re doing something more advanced with WordPress routing, you may need to flush the router manually. Just navigate to Settings -> Permalinks and simply hit Save Changes.

Last updated on