Fix Safari iOS reload loop with static device detection and caching
All checks were successful
Build And Push Image / docker (push) Successful in 3m7s
All checks were successful
Build And Push Image / docker (push) Successful in 3m7s
- Replace reactive device detection with static utilities to prevent infinite reload loops on mobile Safari - Add static-device-detection.ts for one-time device info computation - Add config-cache.ts for improved configuration loading performance - Apply mobile Safari viewport and CSS optimizations across auth pages - Remove reactive dependencies that caused rendering issues on iOS
This commit is contained in:
@@ -163,8 +163,13 @@ definePageMeta({
|
||||
middleware: 'guest'
|
||||
});
|
||||
|
||||
// Static CSS classes based on device (no reactive dependencies)
|
||||
const containerClasses = ref('password-setup-page');
|
||||
import { getStaticDeviceInfo, getDeviceCssClasses, applyMobileSafariOptimizations, getMobileSafariViewportMeta } from '~/utils/static-device-detection';
|
||||
|
||||
// Static device detection - no reactive dependencies
|
||||
const deviceInfo = getStaticDeviceInfo();
|
||||
|
||||
// Static CSS classes - computed once, never reactive
|
||||
const containerClasses = ref(getDeviceCssClasses('password-setup-page'));
|
||||
|
||||
// Reactive state
|
||||
const loading = ref(false);
|
||||
@@ -238,7 +243,7 @@ useHead({
|
||||
name: 'description',
|
||||
content: 'Set your password to complete your MonacoUSA Portal registration.'
|
||||
},
|
||||
{ name: 'viewport', content: 'width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no' }
|
||||
{ name: 'viewport', content: getMobileSafariViewportMeta() }
|
||||
]
|
||||
});
|
||||
|
||||
@@ -306,35 +311,20 @@ const setupPassword = async () => {
|
||||
}
|
||||
};
|
||||
|
||||
// Component initialization
|
||||
// Component initialization - Safari iOS reload loop prevention
|
||||
onMounted(() => {
|
||||
console.log('[setup-password] Password setup page loaded for:', email.value);
|
||||
|
||||
// Static device detection from Nuxt Device Module - no reactive dependencies
|
||||
const { isMobile, isIos, isSafari } = useDevice();
|
||||
|
||||
// Detect mobile Safari specifically
|
||||
const isMobileSafari = isMobile && isIos && isSafari;
|
||||
|
||||
// Apply classes once (static, no reactivity)
|
||||
const containerClassList = ['password-setup-page'];
|
||||
if (isMobile) containerClassList.push('is-mobile');
|
||||
if (isMobileSafari) containerClassList.push('is-mobile-safari');
|
||||
if (isIos) containerClassList.push('is-ios');
|
||||
containerClasses.value = containerClassList.join(' ');
|
||||
// Apply mobile Safari optimizations early
|
||||
if (deviceInfo.isMobileSafari) {
|
||||
applyMobileSafariOptimizations();
|
||||
console.log('[setup-password] Mobile Safari optimizations applied');
|
||||
}
|
||||
|
||||
// Check if we have required parameters
|
||||
if (!email.value) {
|
||||
errorMessage.value = 'No email address provided. Please use the link from your verification email.';
|
||||
}
|
||||
|
||||
// Prevent auto-zoom on iOS when focusing input fields
|
||||
if (isIos) {
|
||||
const metaViewport = document.querySelector('meta[name="viewport"]');
|
||||
if (metaViewport) {
|
||||
metaViewport.setAttribute('content', 'width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no');
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
@@ -138,8 +138,13 @@ const error = ref('');
|
||||
let verificationStarted = false;
|
||||
let verificationComplete = false;
|
||||
|
||||
import { getStaticDeviceInfo, getDeviceCssClasses, applyMobileSafariOptimizations, getMobileSafariViewportMeta } from '~/utils/static-device-detection';
|
||||
|
||||
// Static device detection - no reactive dependencies
|
||||
const deviceInfo = getStaticDeviceInfo();
|
||||
|
||||
// Static container classes - compute once to prevent re-renders
|
||||
let containerClasses = 'verification-page';
|
||||
let containerClasses = getDeviceCssClasses('verification-page');
|
||||
|
||||
// Set page title with mobile viewport optimization
|
||||
useHead({
|
||||
@@ -149,7 +154,7 @@ useHead({
|
||||
name: 'description',
|
||||
content: 'Verifying your email address for the MonacoUSA Portal.'
|
||||
},
|
||||
{ name: 'viewport', content: 'width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no' }
|
||||
{ name: 'viewport', content: getMobileSafariViewportMeta() }
|
||||
]
|
||||
});
|
||||
|
||||
@@ -236,24 +241,15 @@ const retryVerification = () => {
|
||||
verifyEmail();
|
||||
};
|
||||
|
||||
// Initialize mobile detection and classes AFTER component is stable
|
||||
// Component initialization - Safari iOS reload loop prevention
|
||||
onMounted(() => {
|
||||
// Only set mobile classes once to prevent re-renders
|
||||
if (typeof window !== 'undefined') {
|
||||
const userAgent = navigator.userAgent;
|
||||
const isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(userAgent);
|
||||
const isIOS = /iPad|iPhone|iPod/.test(userAgent) && !(window as any).MSStream;
|
||||
const isSafari = /^((?!chrome|android).)*safari/i.test(userAgent);
|
||||
const isMobileSafari = isIOS && isSafari;
|
||||
|
||||
const classes = ['verification-page'];
|
||||
if (isMobile) classes.push('is-mobile');
|
||||
if (isMobileSafari) classes.push('is-mobile-safari');
|
||||
if (isIOS) classes.push('is-ios');
|
||||
containerClasses = classes.join(' ');
|
||||
}
|
||||
|
||||
console.log('[auth/verify] Component mounted with token:', token?.substring(0, 20) + '...');
|
||||
|
||||
// Apply mobile Safari optimizations early
|
||||
if (deviceInfo.isMobileSafari) {
|
||||
applyMobileSafariOptimizations();
|
||||
console.log('[auth/verify] Mobile Safari optimizations applied');
|
||||
}
|
||||
|
||||
// Start verification process with a small delay to ensure stability
|
||||
setTimeout(() => {
|
||||
|
||||
Reference in New Issue
Block a user