Repository navigation
Migrating a Next.js (App Router + Server Components/Actions) app from Capacitor server.url to an embedded, offline-first build (Android + iOS). Who has done it? #8627
Replies: 3 comments
|
1. Server Components / Server Actions An embedded build has no server, so Server Actions aren't available (
2. A dynamic segment without // app/events/page.tsx -> /events?id=123
import { Suspense } from 'react'
import EventView from './event-view'
export default function Page() {
return <Suspense><EventView /></Suspense>
}// app/events/event-view.tsx
'use client'
import { useSearchParams } from 'next/navigation'
export default function EventView() {
const id = useSearchParams().get('id')
// load the event by id with supabase-js
return <main>Event {id}</main>
}Map deep links like 3. Live Updates
4. Android vs iOS
import { createClient } from '@supabase/supabase-js'
import { Preferences } from '@capacitor/preferences'
const nativeStorage = {
getItem: async (key: string) => (await Preferences.get({ key })).value,
setItem: (key: string, value: string) => Preferences.set({ key, value }),
removeItem: (key: string) => Preferences.remove({ key }),
}
export const supabase = createClient(SUPABASE_URL, SUPABASE_ANON_KEY, {
auth: { storage: nativeStorage, persistSession: true, autoRefreshToken: true, detectSessionInUrl: false },
})
5. Gradual migration Yes. Keep Checked against Next.js 16.3.6. |
|
Im not sure about the reply above but capacitors own config doc marks server.url as "intended for use with live-reload servers" and "not intended for use in production", so the black screen on weak signal is just what that mode does the catch is next, not capacitor. an embedded build means output: 'export', and the static export docs list what stops working: server actions, route handlers that read the request, cookies, headers, isr, draft mode, and dynamic routes without generateStaticParams. server components can stay as long as they resolve at build time i think, but every server action has to become a plain api call to your backend (supabase straight from the client, or an api route hosted seperately). thats usually the bulk of the migration live updates for the bundle afterwards is a plugin thing (appflow or capgo), capacitor core doesnt ship it, but it slots in once the app is a static bundle. i wouldnt try to keep server.url and fix it with service worker tricks tho, u already saw how that goes on wkwebview |
|
In case you need guide to NextJs in capacitor we maintain one here https://capgo.app/blog/building-a-native-mobile-app-with-nextjs-and-capacitor/ |
Uh oh!
There was an error while loading. Please reload this page.
I have an app in production on Android and iOS built with Next.js 16 (App Router, Server Components, Server Actions) + Supabase, wrapped with Capacitor 8 loading the remote site through server.url. It also runs as a PWA (Serwist service worker, data cached in IndexedDB).
The requirement: users must open and use the app offline and on weak signal (the "connected but nothing loads" 4G case), like Spotify or Google Maps offline. Usage is mostly reading, with a few writes queued offline.
What I've learned so far: the Capacitor team says server.url is meant for development, not production. That matches our experience: on a cold start with weak signal the WebView sits on a black screen for 30s+ and falls into errorPath, because the app shell doesn't live on the device. Service-worker tweaks (NetworkFirst, CacheFirst, StaleWhileRevalidate, navigation preload) helped in some cases and broke others, and they behave differently on Android WebView and iOS WKWebView (App-Bound Domains, storage eviction).
The direction seems clear: embed the front-end in the binary and use Live Updates for OTA. My questions are about the migration:
Real-world experience, repositories or articles are very welcome. Thanks!
All reactions