Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to get custom install prompt to work Nuxt 3 #649

Open
chronicadventure opened this issue Jan 22, 2024 · 0 comments
Open

Unable to get custom install prompt to work Nuxt 3 #649

chronicadventure opened this issue Jan 22, 2024 · 0 comments

Comments

@chronicadventure
Copy link

chronicadventure commented Jan 22, 2024

I have a component that shows up with an install button. Once the user clicks the install button I'm using await $pwa.install() but no install prompt shows up. There are no console errors and there are no manifest errors in the chrome application tab. Here is my manifest file:

    manifest: {
      name: 'Chronic Adventure',
      description: "Your road life companion for van lifers and RV enthusiasts. Map your travels, share your favorite spots, and discover new adventures with a community that travels with you.",
      theme_color: '#E8ECF5',
      short_name: 'Chronic',
      start_url: '/',
      display: 'standalone',
      "icons": [
        {
          "src": "pwa/android/android-launchericon-512-512.png",
          "sizes": "512x512"
        },
        {
          "src": "pwa/android/android-launchericon-512-512.png",
          "sizes": "512x512",
          "purpose": "any"
        },
        {
          "src": "pwa/android/android-launchericon-512-512.png",
          "sizes": "512x512",
          "purpose": "maskable"
        },
        {
          "src": "pwa/android/android-launchericon-192-192.png",
          "sizes": "192x192"
        },
        {
          "src": "pwa/android/android-launchericon-144-144.png",
          "sizes": "144x144"
        },
        {
          "src": "pwa/android/android-launchericon-96-96.png",
          "sizes": "96x96"
        },
        {
          "src": "pwa/android/android-launchericon-72-72.png",
          "sizes": "72x72"
        },
        {
          "src": "pwa/android/android-launchericon-48-48.png",
          "sizes": "48x48"
        },
        {
          "src": "pwa/ios/16.png",
          "sizes": "16x16"
        },
        {
          "src": "pwa/ios/20.png",
          "sizes": "20x20"
        },
        {
          "src": "pwa/ios/29.png",
          "sizes": "29x29"
        },
        {
          "src": "pwa/ios/32.png",
          "sizes": "32x32"
        },
        {
          "src": "pwa/ios/40.png",
          "sizes": "40x40"
        },
        {
          "src": "pwa/ios/50.png",
          "sizes": "50x50"
        },
        {
          "src": "pwa/ios/57.png",
          "sizes": "57x57"
        },
        {
          "src": "pwa/ios/58.png",
          "sizes": "58x58"
        },
        {
          "src": "pwa/ios/60.png",
          "sizes": "60x60"
        },
        {
          "src": "pwa/ios/64.png",
          "sizes": "64x64"
        },
        {
          "src": "pwa/ios/72.png",
          "sizes": "72x72"
        },
        {
          "src": "pwa/ios/76.png",
          "sizes": "76x76"
        },
        {
          "src": "pwa/ios/80.png",
          "sizes": "80x80"
        },
        {
          "src": "pwa/ios/87.png",
          "sizes": "87x87"
        },
        {
          "src": "pwa/ios/100.png",
          "sizes": "100x100"
        },
        {
          "src": "pwa/ios/114.png",
          "sizes": "114x114"
        },
        {
          "src": "pwa/ios/120.png",
          "sizes": "120x120"
        },
        {
          "src": "pwa/ios/128.png",
          "sizes": "128x128"
        },
        {
          "src": "pwa/ios/144.png",
          "sizes": "144x144"
        },
        {
          "src": "pwa/ios/152.png",
          "sizes": "152x152"
        },
        {
          "src": "pwa/ios/167.png",
          "sizes": "167x167"
        },
        {
          "src": "pwa/ios/180.png",
          "sizes": "180x180"
        },
        {
          "src": "pwa/ios/192.png",
          "sizes": "192x192"
        },
        {
          "src": "pwa/ios/256.png",
          "sizes": "256x256"
        },
        {
          "src": "pwa/ios/512.png",
          "sizes": "512x512"
        },
        {
          "src": "pwa/ios/1024.png",
          "sizes": "1024x1024"
        }
      ],
      screenshots: [
        {
          "src": "profileScreenShot.jpg",
          "type": "image/jpg",
          "sizes": "1080x2316"
        },
        {
          "src": "bookmarksScreenShot.jpg",
          "type": "image/jpg",
          "sizes": "1080x2316"
        },
        {
          "src": "feedScreenShot.jpg",
          "type": "image/jpg",
          "sizes": "1080x2316"
        },
        {
          "src": "profileScreenShot.jpg",
          "type": "image/jpg",
          "sizes": "1080x2316",
          "form_factor" : "wide"
        },
        {
          "src": "bookmarksScreenShot.jpg",
          "type": "image/jpg",
          "sizes": "1080x2316",
          "form_factor" : "wide"
        },
        {
          "src": "feedScreenShot.jpg",
          "type": "image/jpg",
          "sizes": "1080x2316",
          "form_factor" : "wide"
        }
      ]

    },
    devOptions: {
      enabled: true,
      suppressWarnings: true,
      navigateFallbackAllowlist: [/^\/$/],
      type: 'module',
    },
    registerType: "autoUpdate",
    client: {
      installPrompt: true
    },
    workbox: {
      //globPatterns: ['**/*.{js,css,html,ico,png,svg}']
    }
  }

Here is the vue component:

<template>
    <div v-if="needsToSeeThePrompt() & isPromptOpen" class="fixed inset-0 flex items-center justify-center p-4 z-50">
        <!-- Overlay -->
        <div class="absolute inset-0 bg-black bg-opacity-50 z-0"></div>

        <!-- Prompt Box -->
        <transition name="fade">
            <div class="bg-white rounded-lg shadow-lg" style="z-index: 2001;">
                <!-- Close Button -->
                <div class="flex justify-end">
                    <button @click="closePrompt" class="text-black">
                        <svg class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
                            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
                                d="M6 18L18 6M6 6l12 12" />
                        </svg>
                    </button>
                </div>
                <!-- Content -->
                <div class="text-center p-6 m-4">
                    <img src="~/assets/images/logo-icon.png" alt="App Icon" class="mx-auto mb-4 h-20 w-20">
                    <!-- Replace with your icon path -->
                    <h2 class="text-xl font-bold mb-2">Install Chronic Adventure</h2>
                    <p class="mb-4">Install this application on your home screen for quick and easy access when you're on
                        the go.</p>

                </div>
                <div v-if="isIos" class="flex justify-center items-center bg-secondary flex-col py-2 rounded-b-lg">
                    <span class="text-sm">Just tap </span>
                    <span class="text-sm mx-1"><img class="h-5" src="~/assets/images/ios-share.svg" /></span>
                    <span class="text-sm"> then 'Add to Home Screen'</span>
                </div>
                <div v-else class="flex justify-center items-center bg-secondary flex-col py-2 rounded-b-lg">
                    <button @click="installOnNonIos" class="btn-primary">Install?</button>
                </div>
            </div>

        </transition>
    </div>
</template>
  
<script>
export default {
    data() {
        return {
            isPromptOpen: true,
            deferredPrompt: null
        }
    },
    created() {
        window.addEventListener("appinstalled", () => {
            console.log('app installed');
        });
    },
    methods: {
        async installOnNonIos() {
            const {$pwa} = useNuxtApp();
            await $pwa.install();
        },
        closePrompt() {
            // Your logic to hide the prompt
            this.isPromptOpen = false;
            //pwaHelper.savePromptShownDate();
        },
        getLastShownTimestamp() {
            const pwaHelper = usePwaHelper();
            return pwaHelper.getLastShownTimestamp();
        },
        savePromptShownDate() {
            const pwaHelper = usePwaHelper();
            pwaHelper.savePromptShownDate();
        },
        isMoreThanTwoWeeksAgo(lastShownDate) {
            const pwaHelper = usePwaHelper();
            return pwaHelper.isMoreThanTwoWeeksAgo(lastShownDate);
        },
        needsToSeeThePrompt() {
            const authHelper = useAuthHelper();
            if (!authHelper.isLoggedIn())
                return false;

            var lastShown = this.getLastShownTimestamp();
            //if we've shown the prompt before but it hasn't been two weeks then the 
            //prompt does not need to be shown again
            if (lastShown && !this.isMoreThanTwoWeeksAgo(lastShown)) {
                return false;
            }

            if (this.isIos) {
                //app already installed on most recent ios device, legacy devices this won't work
                //you can't have standalone pwa installed
                if (('standalone' in window.navigator) && (window.navigator.standalone)) {
                    return false;
                }

                return true;

            }

            return true;
        }
    },
    computed: {
        isIos() {
            const pwaHelper = usePwaHelper();
            return pwaHelper.isIos();
        }
    }
}
</script>
  
<style>
/* You can add your global styles here */
.fade-enter-active,
.fade-leave-active {
    transition: opacity .5s;
}

.fade-enter,
.fade-leave-to

/* .fade-leave-active in <2.1.8 */
    {
    opacity: 0;
}
</style>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant