Hey Capacitor community! I’m having an issue here with my mobile application built with Capacitor and Next.js particularly connected with Clerk authentification and hoping someone has run into this before, or have any idea how I could solve it.
My app works great when I build it through Xcode for testing, but once it’s on the App Store, authenticated users only when they’re authenticated and close the app and open after a while, or in general after leave it for a while reopen again get redirected to Safari, to server url of my app.
Has anyone dealt with authentication providers redirecting to Safari in production but not development? Any help would be amazing!
Application Setup
Stack:
-
Next.js 14.2.26 with App Router
-
Capacitor 5.7.8 for mobile wrapper
-
Clerk for authentication with production keys
-
Deployment: Live web app architecture (mobile.fuxam.app)
Capacitor Configuration:
const config: CapacitorConfig = {
appId: "com.example.app",
appName: "MyApp",
webDir: "out",
server: {
url: "https://mobile.example.com/",
cleartext: true,
allowNavigation: [
"http://localhost:*",
"*.example.com",
"example.com",
"https://*.example.com",
"https://example.com",
"https://*.example.com/*",
"https://example.com/*",
"*.clerk.accounts.dev",
"https://*.clerk.accounts.dev",
"https://*.clerk.accounts.dev/*",
"https://clerk.example.com",
"https://clerk.example.com/*",
"https://test-app-123.clerk.accounts.dev",
"https://test-app-123.clerk.accounts.dev/*",
],
},
};
import { clerkMiddleware } from "@clerk/nextjs/server";
export default clerkMiddleware();
export const config = {
matcher: ["/((?!.+\\.[\\w]+$|_next).*)", "/", "/(api|trpc)(.*)"],
};
Authentication Flow:
-
Using Clerk Elements for sign-in UI
-
Client-side navigation with Next.js router
The Problem
Works Perfectly: Development builds via Xcode
-
Sign in → Works
-
App backgrounding/foregrounding → Works
-
Session persistence → Works
-
No Safari redirects
Fails in Production: App Store builds
-
Initial sign in → Works
-
User navigates app → Works
-
But after app backgrounding or closing/reopening when user is signed in only and opens again:
-
App automatically redirects to Safari
-
Opens URLs like: https://clerk.example.app/v1/client/handshake?redirect_url=https%3A%2F%2Fmobile.example.app%2F
-
User sees authentication in Safari browser
-
Returning to app shows either empty screen or redirects again to safari with sign-in page
-
Session appears lost in WebView
Technical Details
Architecture: The app uses a live web app model where the native app is essentially a WebView wrapper pointing to https://mobile.example.app/. No traditional app updates - web changes are instantly available.
Suspected Root Cause: iOS WebView security policies differ between development and production builds:
-
Development: Debug provisioning + relaxed WKWebView policies
-
Production: Distribution provisioning + strict navigation enforcement
Authentication Flow Issue:
-
User signs in successfully in WebView
-
Clerk attempts session refresh/validation
-
Navigation to clerk.example.app occurs
-
Production WKWebView delegates this to iOS system (Safari)
-
Session context is lost when returning to WebView
Questions for Community
-
Is allowNavigation sufficient for keeping Clerk authentication flows within WKWebView in production?
-
Are there additional iOS-specific configurations needed for production builds that aren’t required in development?
-
Should we be using iosScheme: “https” or other iOS-specific settings for authentication domains?
-
Has anyone solved similar session persistence issues with third-party authentication providers in production Capacitor apps?
Any insights on why this behavior differs between Xcode development builds and App Store distribution builds would be greatly appreciated!