What are blank screen redirect rejections?
Apple rejects apps that flash white screens during login When your app redirects to an external OAuth page and back, users often see a blank white screen for a moment. Apple considers this a poor user experience and will reject your app. Common rejection messages:- “The app displays a blank screen during the authentication process”
- “Users experience a white flash when signing in”
- “The login flow does not provide adequate visual feedback”
- “The app appears unresponsive during authentication”
Why this happens
Web redirects cause visible loading gaps The traditional OAuth redirect flow works like this:- User taps “Sign in with Apple”
- Browser redirects to apple.com → blank screen
- User authenticates on Apple’s page
- Apple redirects back to your callback URL → blank screen
- Callback page processes tokens
- Redirect to app home
- Using redirect-based OAuth instead of Apple JS SDK on iOS/Web
- Google
/native-callbackpage relies on React instead of static HTML - No loading state shown while backend processes tokens (React apps)
How to fix it
Use Apple JS SDK instead of redirects
The JS SDK shows a native dialog with no redirects On iOS and Web, the Apple JS SDK opens a native authentication dialog. There’s no redirect to apple.com, so no blank screen.| Platform | Experience |
|---|---|
| iOS (native) | Face ID dialog appears instantly |
| iOS (Safari) | Native Apple dialog, no redirect |
| Web (Chrome/Firefox) | Apple popup window |
| Android | Must use oauth:// (see below) |
Apple JS SDK needs a loading component (not static HTML)
The JS SDK returns credentials to JavaScript, then you show a loading state Unlike redirect flows, the Apple JS SDK returns credentials directly to your JavaScript. You then need to verify these with your backend. During verification, show a loading screen. The flow:AppleID.auth.signIn()shows native dialog- User authenticates (Face ID on iOS, popup on web)
- Credentials (
id_token,code,user) returned to JavaScript - Navigate to loading page/component
- Loading page POSTs credentials to backend API
- Backend verifies token, returns JSON with session tokens
- Frontend sets session, navigates to app
| Flow | Loading screen | Backend response |
|---|---|---|
| Apple JS SDK (iOS/Web) | React component | JSON |
| Apple form_post (Android) | Apple’s page (during processing) | 302 redirect to deeplink |
| Google oauth:// (native) | Static HTML page | N/A (client-side) |
Google and other standard OAuth use /native-callback
The native-callback page IS your loading screen for Google For Google Sign In on native (and other OAuth providers that use standard redirects), the authentication happens in a secure browser session. When the OAuth provider redirects back, it lands on your/native-callback page which serves as the loading screen.
Note: Apple Sign In on Android is different. It uses form_post directly to your backend, which processes and redirects. See “Apple Sign In on Android” section.
despia('oauth://?url=...')opens secure browser- User authenticates with Google
- Google redirects to
/native-callback /native-callbackshows loader while processing tokens- Redirects to
myapp://oauth/auth?tokensto close browser and return to app
/native-callback page must render a loader immediately via static HTML.
Serve static HTML on callback pages (Google native)
Callback pages need static HTML loaders, not React When Google redirects to your/native-callback page, that page must display a loading spinner before any JavaScript framework loads. React components won’t render fast enough.
This applies to:
/native-callbackfor Google OAuth on native- Any OAuth redirect callback page (not Apple on Android)
- Apple JS SDK flow (use React loading component instead)
- Apple on Android (backend handles form_post and redirects)
- Pages you navigate to within your app
The native-callback page is your client-side loading screen
For Google and other standard OAuth flows using oauth:// Your/native-callback page is a client-side page that renders a loading screen while processing tokens and redirecting back to the app via deeplink. This is used for:
- Google Sign In on iOS and Android
- Any OAuth provider that redirects back to a client-side URL
Apple Sign In on Android: backend processes then redirects
Apple’s form_post is handled entirely server-side Apple Sign In on Android usesresponse_mode: form_post, which POSTs directly to your backend. The backend processes everything (verify token, create user, generate session) and then returns a 302 redirect to the deeplink. No HTML is served.
The flow:
oauth://opens ASWebAuthenticationSession- User authenticates on Apple’s page
- Apple POSTs form_post to your backend endpoint
- Backend verifies token, creates/finds user, generates session tokens
- Backend returns 302 redirect to
myapp://oauth/auth?tokens - Deeplink closes browser, app navigates to
/auth?tokens - App sets session
- Apple’s page (with Apple’s own loading states)
- Brief processing (browser shows Apple’s page still)
- Browser closes, back in app
Match your app’s design
The loader should feel like part of your app Use your app’s colors, fonts, and branding in the loading screen. This makes the transition seamless.Quick checklist
Apple Sign In on iOS and Web (JS SDK):- Apple JS SDK loaded in index.html
signIn()called for native dialog- Credentials returned to JavaScript (no redirect)
- Navigate to React loading component with credentials
- Loading component POSTs to backend API
- Backend returns JSON (not HTML)
- Frontend sets session
- Backend endpoint handles form_post from Apple
- Backend processes everything server-side (verify, create user, generate session)
- Backend returns 302 redirect to deeplink
- No HTML served (Apple’s page stays visible during processing)
/native-callbackpage has static HTML loader- Loader renders before JavaScript executes
- Tokens processed client-side
- Deeplink redirect happens after loader is visible
- Static HTML with inline CSS (not external stylesheet)
- Spinner/loader visible immediately on page load
- No blank/white screen at any point
- Design matches your app theme
Common rejection reasons
| Rejection | Fix |
|---|---|
| ”Blank screen during auth” | Use Apple JS SDK instead of redirect on iOS/Web |
| ”White flash on Google login” | Add static HTML loader to /native-callback page |
| ”Unresponsive during sign in” | Show loading state while backend processes tokens |
| ”Poor authentication UX” | Match loader design to app theme |
Platform summary
| Platform | Apple Sign In | Google Sign In | Callback handling |
|---|---|---|---|
| iOS (Despia) | JS SDK → React loading | oauth:// → /native-callback | React component / Static HTML |
| iOS (Safari) | JS SDK → React loading | Standard OAuth | React component |
| Android (Despia) | oauth:// → backend → 302 redirect | oauth:// → /native-callback | Backend redirect / Static HTML |
| Web | JS SDK → React loading | Standard OAuth | React component |
- Apple JS SDK (iOS/Web): Returns credentials to JS. Navigate to React loading component, POST to backend for JSON response.
- Apple on Android: Backend receives form_post, processes everything server-side, returns 302 redirect to deeplink. No HTML served.
- Google on native: Redirects to
/native-callbackclient-side page. Page must have static HTML loader.
Still stuck?
If you keep getting rejected for blank screens:- Record your login flow and watch for any white/blank frames
- Check that callback pages have inline CSS loaders (not just JS)
- Test on slow network to see if loader appears before JS loads
- Contact support: support@despia.com with:
- Screen recording of your login flow
- Your rejection notice in full
- URLs of your callback pages