Worst kind of bug when migrating Iron Router to Meteor 3: the kind that produces zero errors.
Iron Router auto-discovers controllers by naming convention. A route called postsShow looks for a global called PostsShowController.
In Meteor 2, top-level assignments were file-scoped globals. It worked.
In Meteor 3, const PostsShowController = ... is module-scoped. Iron Router can't find it.
But the route still renders. Page loads. No console errors. Subscriptions never fire. Database has thousands of docs, Minimongo shows zero.
The fix: stop relying on naming convention. Pass the controller explicitly.
this.route('postsShow', {
path: '/posts/:slug',
controller: PostsShowController,
});
Do this for every route with a controller in Meteor 3.