Router/navigation support
See original GitHub issueIf using Next.js and building both an iOS/Android app and a web app/PWA, you’ll need both support for Next.js routing and also quality client-side routing.
This way you can serve up any valid page by navigating directly to it on the web (say, /about
), complete with static rendering and possibly even SSR, but also navigate to an about
page client-side complete with transitions and quality native experience users expect.
I wanted to document what I think the best approach here is which is @creativiii’s hybrid next/local approach (see his post on this: https://ironeko.com/posts/animating-page-transitions-in-nextjs-for-capacitor?ref=last_articles)
App Shell
The core idea is that every page serves up an <AppShell>
component that is essentially all of the Nav
, Menu
, Tabs
, and PageStack
needed to build the actual client app experience:
Client-side routing
Then, instead of using Next.js for actual client-side navigation, we will use a simple client-side router like Wouter: https://github.com/molefrog/wouter
This will handle the “local, client-side” navigation and transitions, but won’t handle any “server-side” requests at all.
Handling Deeplinks
Most apps will want to handle universal links, but the way those URLs are handled is quite different from a product web server and a mobile app which is not running a web server.
Thus, the app will need to handle deeplinks (https://capacitorjs.com/docs/guides/deep-links) and process each request. If it detects that there is an in-app handler for that URL, it will navigate client-side to that page. If not, it will let the browser handle the URL.
Example page
This is an example of what the Next.js page code would contain:
import AppShell from '../components/AppShell';
import Home from '../components/pages/Home';
export default function Index() {
return <AppShell page={Home} />;
}
usePage
hook
Then, each page component can use the usePage
hook to configure app shell related values, such as the title of the page, icons for the tabs, and other values
const Home = ({ selected }) => {
usePage({
title: 'Home',
});
return (
...
)
}
Tasks
- Abstract away page structure into
AppShell
component - Test/integrate client-side router like Wouter
- Build simple navigation transitions
- Verify static/SSR support along with client-side routing
Issue Analytics
- State:
- Created 3 years ago
- Reactions:1
- Comments:10 (6 by maintainers)
Top GitHub Comments
Turns out it’s not 😭 at least not officially. However I’m optimistic there’s a middle ground. At the very worst it could require two Next.js apps with one just for SSRing but sharing code. There are some hacky workarounds here that I’m going to look into: https://github.com/vercel/next.js/discussions/15674
At the very least the
getStaticProps
will work fine for now.Closing as I ended up going with a solution that primarily has Ionic handle routing client side (so you get all the nice transitions and history stack management), and next.js handles any initial load routes and renders the app shell. Works great for iOS and Android apps, not ideal for PWAs but this specific project is initially focused on app store apps.