Replies: 4 comments 18 replies
-
I haven't worked with Solito personally (came across this repo from one of Fernando's talks), but thought it would be worth sharing my experience building a Vite SSR-based universal router which makes use of native navigation patterns (stack navigators, tab navigators, etc.) ContextI'm working on a hybrid cross-platform framework which adheres to two fundamental philosophies:
Also note that I'm actually building on top of Astro as a base framework. Astro is essentially just a light wrapper over Vite in SSR mode—analagous to the way
as they are essentially the same thing. A navigation implementation in any of these modes should be easily portable to any of the others. Strategy, rationale & complicationsUnlike Solito's approach of splitting navigation responsibility between IMO this was the only feasible way to get server rendering working because of the explosion in complexity when you combine cross-platform inconsistencies with client/server handoff. Furthermore, I soon realised why no (decent) modern cross-platform routing solution currently exists despite the obvious need for one - because it's bloody hard to build 😬. Here are just some additional complications that must be handled:
A couple more tricks I used were to borrow (i.e. steal) Nate's Anyway, after tearing my hair out for a few weeks fighting all these issues, I managed to get a working MVP locally. It's an isomorphic router (free of hydration issues!) with first-class support for stack + tab navigators and SSR. Conceptually it's a similar approach taken by Expo Router; however, with native Vite & SSR integration (Expo is tightly coupled to Metro and currently only supports static page generation). I hope this post provided you or others reading with some insight. P.S. if you're not aware, in the time since you wrote this post, Hydrogen announced it's no longer supporting RSCs. But Shopify also acquired Remix which announced it is working on RSC support, so... 🙄 |
Beta Was this translation helpful? Give feedback.
-
Good questions - firstly, I should've been clearer in explaining that what I'm trying to build specifically is a webview-based framework by leveraging core RN libraries that work with react-native-web, and supplementing any native functionality with Capacitor plugins. So sort of like a modern take on quasar or Ionic. Therefore, in my previous post, by server-driven UI I mean meant server-rendered HTML. But here's where it gets interesting if you're attempting to build a server-driven solution using the conventional RN strategy of deploying native iOS & Android builds. In case you weren't aware, some context: a server components endpoint doesn't actually ship HTML to the client. Rather, it streams something called an "RSC payload". This is serialised JSON which the client React renderer then uses to work out what to diff/reconcile in the vDOM tree to update the UI with the server response. The above is really the key point IMO because it means we'd derive the most value focusing on a Vite RSC implementation. This can then have routing logic layered on top. In this way, we'd finally have cross-platform server-driven UI & navigation, instead of all the current intermediate workarounds. **in writing this, I literally just came across this tweet from Evan Bacon which gives me even more confidence that it's the approach to take. Super cool! To answer your second question: basically, yes, running react-navigation on the server: https://reactnavigation.org/docs/server-rendering/ It's a bit involved to explain so hopefully I can just get a demo up soon. I render a shell of the requested route as an Astro island which is then hydrated client-side. And it does use react-native-screens, though on web you can omit this and react-navigation will fall back to react-native-web's default
Sounds great, I'm a big fan of your work. Keep it up! |
Beta Was this translation helpful? Give feedback.
-
@jkhaui Thanks for the detailed response! I’m not entirely sure of the setup you’re envisioning… Is it similar to tech strategy 6.2 «Turbo Native w/ React Native shell« or nr 7 «React inside React Native WebView [hybrid]» in this article: https://dev.to/this-is-learning/the-different-strategies-to-building-a-cross-platform-app-3p56 ? But using Capacitor instead of React Native for the shell app? Let me see if I get this correct: You have a CapacitorJS shell app, which bundles a native Web View, which again loads the webapp on-demand from the server. On the server you SSR the webapp with Astro mainly as a big Island made with React Native Web (which is then hydrated in the client Web View). It does sound a bit convoluted.. Note that CapacitorJS by default bundles all HTML/CSS/JS with the app that is shipped to the App Store. Even if it is in a Web View. Since Apple is more likely to reject shell apps that load the HTML/CSS/JS from the server on demand (with the reason «the web is for that», requiring some Minimum Native Functionality). Not sure why Astro is a particularly good fit either, if you don’t render parts of the page potentially in pure HTML? If it’s only a single big island anyway, why not bare metal Vite or even vite-plugin-ssr aka Vike ? Also, if you’re using React Native Web, why not take advantage of the React Native part of it on native? If you only ever load it from the web server and in a Web View, couldn’t you just use React then, and get access to the wider web ecosystem/libraries, and deal with less potential cross-compat issues between RN and web? Not to mention where RSC’s really fit into this… Why bother with RSC’s (to avoid shipping JS bundles and hydration) if you are already using Astro which can avoid sending JS bundles and just SSR and ship the pure HTML (which doesn’t need hydration and is lighter than JSON wire format that RSC uses)? PS: If it at all makes sense to go the RSC route* then for potential inspiration/collaboration, here is a vite-rsc reference implementation made by cyco130 the author of RakkasJS. ‘* I’m with Nate here in questioning the utility of RSC’s, due to complex setup («use server» and whatnot), convoluted mental model / onboarding issues, and RSC’s requiring more server work/interactions and network round trips. I’d rather have offline-first than server/hostingprovider-centric ! |
Beta Was this translation helpful? Give feedback.
-
Thanks Nate and Fernando for your feedback. I’ve really enjoyed listening to talks from both of you, so it’s interesting to hear your takes on how we should evolve navigation in a universal stack. Fair bit to unpack in this thread - I’ll start with Nate and collaboration. I’m definitely keen, let me know the best way to get in touch with you. I’ve been thinking: even if we might all have different visions/goals for where to take this, there’s surely some common work involving Vite + react-navigation that would benefit us all. What comes to mind atm:
This way we could theoretically all reap the benefits of sharing underlying web navigation setup while still maintaining the freedom to build the rest of the stack in whatever way we want (RSC/no RSC, single webview vs RN platform-specific approach, vanilla Vite vs. Vite-based framework, etc.). What do you all think? |
Beta Was this translation helpful? Give feedback.
-
Would be awesome if someone made a Solito-like implementation but for Vite (to work with one of its awesome Vite SSR libraries/frameworks, instead of NextJS (which is likely forever tied to Webpack). Where @brillout's
vite-plugin-ssr
looks the most promising.Why do this? Well, to quote @nandorojo :
My response:
Some benefits of vite-plugin-ssr:
Tagline for
solito-vite
/solito-vite-plugin-ssr
could be "A library dedicated to unifying React Native with vite-plugin-ssr, primarily focused on navigation."(In the same spirit as solito-remix or solito-redwood.)
Just throwing the idea out there. Fully understand if it won't be on Fernando's radar, since I imagine untying from NextJS might be a hassle.
Solito is supposedly a tiny wrapper library, that looks like it has about 2000 lines of TS & JS code.
@natew of Tamagui is currently brewing on something Vite-related, but he's currently using (parts of?) Hydrogen because of its Vite and cutting edge React Server Components support. But Hydrogen is a framework for making Shopify storefronts, so relying on it wholesale won't generalize as well to all kinds of universal apps.
Update 2023-10-24: Link to Discord discussion: https://discord.com/channels/1085921563372703815/1166451963974668319
Beta Was this translation helpful? Give feedback.
All reactions