var, so redirect_canonical 301s `/page/2` back to page 1. Route::get('/page/{pageNumber}', [new TopicsController(), 'index']); // The member's own notifications - matches frontend route '/notifications'. // Declared before the single-segment '/{slug}' route below, which would // otherwise take it and look for a topic by that name. Static beats dynamic // here only because this is declared first; the router matches in order. Route::get('/notifications', [new NotificationsPageController(), 'show']); // What the member follows - matches frontend route '/following'. Before // '/{slug}' for the same reason as '/notifications'. Route::get('/following', [new FollowingPageController(), 'show']); // Auth screens - match the frontend routes '/login', '/register', // '/verify-email' and '/forgot-password'. Declared before '/{slug}' for the same // reason as '/notifications': otherwise they are looked up as topics and 404. Route::get('/login', [new AuthPageController(), 'login']); Route::get('/register', [new AuthPageController(), 'register']); Route::get('/verify-email', [new AuthPageController(), 'verifyEmail']); Route::get('/forgot-password', [new AuthPageController(), 'forgotPassword']); // Member profile - matches frontend route '/user/:userId'. Declared before the // single-segment topic route below; it is two segments, so it cannot be served // by '/{slug}' and would otherwise fall through to a WordPress 404. Route::get('/user/{userId}', [new UserProfilePageController(), 'show']); // Term archives - matches frontend route '/:archiveSegment/:termSlug'. Declared // after the profile route so `/user/{id}` still wins, and before the topic route // below, which is single-segment and cannot match these anyway. An unknown // segment or term is turned into a 404 by the controller rather than here. Route::get('/{segment}/{termSlug}', [new TopicArchiveController(), 'show']); // A link to one reply - matches frontend route '/:postName/comment/:commentId'. // The topic page itself, with the portal scrolling to the reply once it loads; // the server has nothing to do with the reply, so a deleted one still answers // with its topic rather than a 404. Three segments, so neither route beside it // can take it. Route::get('/{slug}/comment/{commentId}', [new TopicDetailsController(), 'show']); // Topic details route - matches frontend route '/topics/details/:id' Route::get('/{slug}', [new TopicDetailsController(), 'show']); // Wildcard route for 404 handling - matches frontend route '*' // Route::any('*', [new NotFoundController(), 'index']);