Fix PWA installation for Brave/Android - Complete rewrite
Critical fixes for PWA installation: 1. ✅ Use proper Vite PWA registration with virtual:pwa-register 2. ✅ Simplified manifest.json (removed verbose name, fixed orientation) 3. ✅ Added 'any maskable' dual-purpose icon for better compatibility 4. ✅ Removed crossorigin from manifest link (causes issues) 5. ✅ Simplified start_url to just '/' 6. ✅ Added msapplication-TileColor meta tag 7. ✅ Set injectRegister: 'auto' in Vite config 8. ✅ Use public/manifest.json directly instead of generating This should now work on Brave Browser Android with proper 'Install App' prompt. Test: Clear site data, visit site, should see install prompt within 30 seconds. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -14,8 +14,10 @@
|
|||||||
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
|
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
|
||||||
<meta name="apple-mobile-web-app-title" content="IndeedHub">
|
<meta name="apple-mobile-web-app-title" content="IndeedHub">
|
||||||
<meta name="application-name" content="IndeedHub">
|
<meta name="application-name" content="IndeedHub">
|
||||||
|
<meta name="msapplication-TileColor" content="#0a0a0a">
|
||||||
|
<meta name="format-detection" content="telephone=no">
|
||||||
<link rel="apple-touch-icon" href="/icons/apple-touch-icon.png">
|
<link rel="apple-touch-icon" href="/icons/apple-touch-icon.png">
|
||||||
<link rel="manifest" href="/manifest.json" crossorigin="use-credentials">
|
<link rel="manifest" href="/manifest.json">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="app"></div>
|
<div id="app"></div>
|
||||||
|
|||||||
@@ -1,26 +1,23 @@
|
|||||||
{
|
{
|
||||||
"name": "IndeedHub - Decentralized Media Streaming",
|
"name": "IndeedHub",
|
||||||
"short_name": "IndeedHub",
|
"short_name": "IndeedHub",
|
||||||
"description": "Stream films and content on the decentralized web powered by Nostr and Bitcoin",
|
"description": "Stream films and content on the decentralized web powered by Nostr and Bitcoin",
|
||||||
"start_url": "/?source=pwa",
|
"start_url": "/",
|
||||||
"scope": "/",
|
"scope": "/",
|
||||||
"display": "standalone",
|
"display": "standalone",
|
||||||
"orientation": "any",
|
"orientation": "portrait-primary",
|
||||||
"background_color": "#0a0a0a",
|
"background_color": "#0a0a0a",
|
||||||
"theme_color": "#0a0a0a",
|
"theme_color": "#0a0a0a",
|
||||||
"prefer_related_applications": false,
|
|
||||||
"icons": [
|
"icons": [
|
||||||
{
|
{
|
||||||
"src": "/icons/icon-192.png",
|
"src": "/icons/icon-192.png",
|
||||||
"sizes": "192x192",
|
"sizes": "192x192",
|
||||||
"type": "image/png",
|
"type": "image/png"
|
||||||
"purpose": "any"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"src": "/icons/icon-512.png",
|
"src": "/icons/icon-512.png",
|
||||||
"sizes": "512x512",
|
"sizes": "512x512",
|
||||||
"type": "image/png",
|
"type": "image/png"
|
||||||
"purpose": "any"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"src": "/icons/icon-192-maskable.png",
|
"src": "/icons/icon-192-maskable.png",
|
||||||
@@ -33,9 +30,15 @@
|
|||||||
"sizes": "512x512",
|
"sizes": "512x512",
|
||||||
"type": "image/png",
|
"type": "image/png",
|
||||||
"purpose": "maskable"
|
"purpose": "maskable"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "/icons/icon-512.png",
|
||||||
|
"sizes": "512x512",
|
||||||
|
"type": "image/png",
|
||||||
|
"purpose": "any maskable"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"categories": ["entertainment", "video", "streaming"],
|
"categories": ["entertainment"],
|
||||||
"lang": "en-US",
|
"lang": "en-US",
|
||||||
"dir": "ltr"
|
"dir": "ltr"
|
||||||
}
|
}
|
||||||
|
|||||||
20
src/main.ts
20
src/main.ts
@@ -3,6 +3,7 @@ import { createPinia } from 'pinia'
|
|||||||
import router from './router'
|
import router from './router'
|
||||||
import App from './App.vue'
|
import App from './App.vue'
|
||||||
import './style.css'
|
import './style.css'
|
||||||
|
import { registerSW } from 'virtual:pwa-register'
|
||||||
|
|
||||||
const app = createApp(App)
|
const app = createApp(App)
|
||||||
|
|
||||||
@@ -11,11 +12,14 @@ app.use(router)
|
|||||||
|
|
||||||
app.mount('#app')
|
app.mount('#app')
|
||||||
|
|
||||||
// Register PWA service worker
|
// Register PWA service worker with auto-update
|
||||||
if ('serviceWorker' in navigator) {
|
const updateSW = registerSW({
|
||||||
window.addEventListener('load', () => {
|
immediate: true,
|
||||||
navigator.serviceWorker.register('/sw.js').catch(() => {
|
onNeedRefresh() {
|
||||||
// Service worker registration failed, that's okay
|
// Auto-reload when new content is available
|
||||||
})
|
updateSW(true)
|
||||||
})
|
},
|
||||||
}
|
onOfflineReady() {
|
||||||
|
console.log('App ready to work offline')
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|||||||
@@ -8,46 +8,12 @@ export default defineConfig({
|
|||||||
vue(),
|
vue(),
|
||||||
VitePWA({
|
VitePWA({
|
||||||
registerType: 'autoUpdate',
|
registerType: 'autoUpdate',
|
||||||
|
injectRegister: 'auto',
|
||||||
includeAssets: ['icons/*.png', 'assets/fonts/*.otf'],
|
includeAssets: ['icons/*.png', 'assets/fonts/*.otf'],
|
||||||
devOptions: {
|
devOptions: {
|
||||||
enabled: false
|
enabled: false
|
||||||
},
|
},
|
||||||
manifest: {
|
manifest: false, // Use public/manifest.json instead
|
||||||
name: 'IndeedHub - Decentralized Media Streaming',
|
|
||||||
short_name: 'IndeedHub',
|
|
||||||
description: 'Stream films and content on the decentralized web powered by Nostr and Bitcoin',
|
|
||||||
theme_color: '#0a0a0a',
|
|
||||||
background_color: '#0a0a0a',
|
|
||||||
display: 'standalone',
|
|
||||||
start_url: '/',
|
|
||||||
scope: '/',
|
|
||||||
icons: [
|
|
||||||
{
|
|
||||||
src: '/icons/icon-192.png',
|
|
||||||
sizes: '192x192',
|
|
||||||
type: 'image/png',
|
|
||||||
purpose: 'any'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
src: '/icons/icon-512.png',
|
|
||||||
sizes: '512x512',
|
|
||||||
type: 'image/png',
|
|
||||||
purpose: 'any'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
src: '/icons/icon-192-maskable.png',
|
|
||||||
sizes: '192x192',
|
|
||||||
type: 'image/png',
|
|
||||||
purpose: 'maskable'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
src: '/icons/icon-512-maskable.png',
|
|
||||||
sizes: '512x512',
|
|
||||||
type: 'image/png',
|
|
||||||
purpose: 'maskable'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
workbox: {
|
workbox: {
|
||||||
maximumFileSizeToCacheInBytes: 10 * 1024 * 1024, // 10 MB limit
|
maximumFileSizeToCacheInBytes: 10 * 1024 * 1024, // 10 MB limit
|
||||||
globPatterns: ['**/*.{js,css,html,ico,png,svg,jpg,jpeg,woff,woff2,otf}'],
|
globPatterns: ['**/*.{js,css,html,ico,png,svg,jpg,jpeg,woff,woff2,otf}'],
|
||||||
|
|||||||
Reference in New Issue
Block a user