Framework7 Router Navigation with Page Transitions: Setup, Example, and Pitfalls
Learn how to set up Framework7’s built‑in router for animated page navigation, see a complete code example, and avoid the most frequent pitfalls.
22 Oct 2025, 10:11 UTC

Useful answer
To get animated, single‑page‑app style navigation in Framework7, define your routes when you create the Framework7 instance and then call app.views.main.router.navigate(). The router loads the component URL, updates the browser address, and applies the default slide transition automatically.
How it works – a worked configuration
Below is a minimal, self‑contained example that shows the three essential parts: the view element, the route table, and the navigation call.
Framework7 Router Demo
Explanation of the key lines:
data-name="main"on the view element gives the router a reference; without itapp.views.mainis undefined.- The
routesarray tells Framework7 which URL should load which HTML fragment. The URLs are fetched via XHR at runtime. - Calling
mainRouter.navigate('/about/', { animate: true })pushes the new URL onto the history stack, fetchesabout.html, inserts it into the view, and runs the default slide transition.
Limits and common mistakes
Scope of the router
The Framework7 router only works inside a View component. If you have multiple views (e.g., a left panel and a main content area), each view needs its own router instance (app.views.left.router, app.views.main.router). Attempting to navigate using the wrong router will silently fail or load the page into the wrong container.
Missing data-name
If you omit the data-name attribute on the view div, app.views.main returns undefined. The navigation call then throws a TypeError like "Cannot read property 'navigate' of undefined". Always verify that the view element has a unique data-name matching the selector you used when creating the view.
Nested views need separate routers
Framework7 does not propagate a parent router to child views. When you create a nested view (e.g., a tab inside a view), you must initialize it with its own routes or share a router instance manually. Forgetting this results in navigation that appears to work but actually loads content into the parent view, breaking the expected layout.
Server‑side rendering is not supported
The router expects the initial HTML to be static or pre‑rendered; it does not hydrate server‑generated markup. If you render the initial page on the server and then try to use the router, the first navigation may duplicate content or leave stale DOM nodes. For SSR‑style workflows, render the full page on the server and disable the router for the initial load.
Lazy‑loaded component URLs must be reachable
When you specify a componentUrl, Framework7 fetches it with an XHR at navigation time. If the URL returns 404 or is blocked by CORS, the router inserts an empty page and shows no error in the UI. You can detect this by watching the network tab for a failed request or checking the console for a warning like "Failed to load component URL". Ensure the component files are served from the same origin or configure proper CORS headers.
Avoid mixing router navigation with manual DOM changes
Manually showing/hiding pages with jQuery, vanilla JS, or CSS while the router is active can interfere with the animation queue. The router expects to be the sole manager of the view’s page elements. If you need to toggle UI outside the router’s scope, do it on elements that are not part of the routed page container.
Practical verification steps
- Create a folder with
index.html(the file above) and two additional files:about.htmlandcontact.htmlcontaining any markup you like. - Open
index.htmlin a browser (served via a local web server to avoid file‑origin XHR restrictions). - Open the developer console.
- Click a button or link that triggers
app.views.main.router.navigate('/about/', { animate: true }). - Observe:
- The URL bar changes to
#/about/(or plain/about/if you use hash‑less mode). - The content of
about.htmlslides into view. - No errors appear in the console.
- The network tab shows a successful GET for
about.htmlwith status 200. - Repeat for the contact page and verify the back button works.
If you see a blank page after navigation, check the network tab for a 404 on the component URL and confirm the view element has the correct data-name. If the transition jumps without animation, ensure you passed { animate: true } (or set the global animate option to true) and that you are not manually overriding the page’s CSS transition properties.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.