Choosing Between Router and Page Components in Framework7
Learn how to distinguish between Framework7 Router and Page components to maintain native-like transitions and correct browser history in your mobile app.
14 Sept 2026, 10:11 UTC

The Navigation Decision: Router vs. Page Components
When building a mobile-centric application with Framework7, the primary technical challenge is managing the navigation stack without sacrificing the native-app feel of page transitions. Developers often confuse the Router Component with the Page Component, but they serve distinct roles: one manages the address and history, while the other manages the view and lifecycle.
The core problem is that using a Router without properly wrapped Page components disables the hardware-accelerated transitions and lifecycle hooks that make Framework7 feel like a native iOS or Android app. Conversely, using Page components without a configured Router leads to a broken browser history, where the 'Back' button exits the app rather than returning to the previous view.
Comparison of Navigation Roles
| Feature | Router Component | Page Component |
|---|---|---|
| Primary Purpose | URL management & History API | Content container & UI transitions |
| State Control | Determines which view to load | Determines how the view behaves |
| Lifecycle Hooks | Navigation events (beforeNavigate) | Page events (pageInit, pageBeforeRemove) |
| SEO/URLs | Handles pushState and deep-linking | No impact on URL structure |
Engineering Trade-offs
Choosing how to structure these components depends on your application's complexity and memory constraints.
- Single-Page Application (SPA) Mode: By enabling
pushStatein the Router, you map internal views to browser URLs. This is essential for web-based apps where users expect to share links to specific pages. However, it requires strict synchronization between the router state and the browser history to avoid "ghost" pages. - Nested Routing: Framework7 allows routers within pages. While powerful for dashboards with independent sub-sections, over-nesting increases memory overhead because each router maintains its own navigation stack.
- Lifecycle Dependency: If you replace a
with a standard, the Router will still change the URL, but thepageInitevent will never fire, and the slide-in animation will be replaced by an abrupt content swap.
Implementation: Routing with Lifecycle Validation
To implement a functional navigation flow, you must define the route in the App configuration and wrap the target content in a Page component. This example assumes Framework7 v8+.
Step 1: Configure the Router (App.js)
Run this configuration in your main application entry point. Ensure you have administrative access to the project source files.
const app = new Framework7({
el: '#app',
routes: [
{ path: '/', component: HomePage },
{ path: '/user/:id/', component: UserProfilePage },
],
view: {
browserHistory: true,
browserHistorySeparator: '#',
},
});
Step 2: Define the Page Component (UserProfilePage.js)
Use the Page component to ensure the pageInit hook triggers when the Router navigates to this path.
export default class UserProfilePage extends Framework7.Component {
params: { id: 'unknown' },
components: {
template: `
<f7-page>
<f7-navbar<
<f7-link route="/" back></f7-link>
<f7-navbar-title>User Profile</f7-navbar-title>
</f7-navbar>
<f7-block>
User ID: {{params.id}}
</f7-block>
</f7-page>
`,
},
pageInit() {
console.log(`Page initialized for user: ${this.params.id}`);
// This is where you trigger API calls for the specific resource
}
}
Verification and Diagnostics
To verify the implementation is working correctly, perform the following checks:
- URL Sync: Trigger navigation using
app.views.main.router.navigate('/user/123/'). Check the browser address bar; it should update to include#user/123/(or the defined separator). - Lifecycle Check: Open the browser console. Upon navigating to the profile page, the
pageInitlog must appear. If it does not, verify that the template is wrapped in<f7-page>. - Transition Check: Observe the animation. If the page snaps into place without a slide effect, the Router is functioning, but the Page component is missing or incorrectly nested.
Limitations and Rollback
Limitations: The Router's pushState can conflict with some server-side redirects if not configured to use a hash separator. In strict SPA environments, ensure your server is configured to redirect all 404s back to index.html.
Rollback: If navigation state becomes corrupted or memory leaks occur due to nested routers, remove the routes array from the App config and revert to manual view manipulation using view.removePageBeforeNavigate to clear the stack.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.