How to make splash screen effect in NuxtJS 3?

Hello everyone, Is NuxtJS 3 support to make splash screen effect like mobile app? so I want the splash screen to only appear once when the app is initialized for the first time.
23 Replies
kapa.ai
kapa.ai3d ago
Hi @Adnan Erlansyah. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- Yes, Nuxt 3 supports creating a splash screen effect similar to mobile apps. You can achieve this by using the SPA loading template feature. Here's how you can implement it: 1. Create a file named spa-loading-template.html in the app directory of your Nuxt 3 project. 2. In this file, add the HTML content for your splash screen. This could include your logo, loading animation, or any other elements you want to display. 3. Nuxt will automatically use this template when rendering client-only pages (with ssr: false). Here's an example of how you can set it up:
<!-- app/spa-loading-template.html -->
<div class="splash-screen">
<img src="/path-to-your-logo.png" alt="Logo">
<p>Loading...</p>
</div>

<style>
.splash-screen {
/* Add your styles here */
}
</style>
<!-- app/spa-loading-template.html -->
<div class="splash-screen">
<img src="/path-to-your-logo.png" alt="Logo">
<p>Loading...</p>
</div>

<style>
.splash-screen {
/* Add your styles here */
}
</style>
By default, Nuxt 3 will render this template alongside the Nuxt app root:
<div id="__nuxt"></div>
<!-- spa loading template -->
<div id="__nuxt"></div>
<!-- spa loading template -->
This approach prevents a flash of white when hydrating a client-only page. To ensure the splash screen only appears once when the app is initialized for the first time, you can use client-side JavaScript to set a flag in localStorage after the first load. For more detailed information on this feature, you can refer to the Nuxt 3 documentation on SPA Loading Template. Remember that this feature is primarily useful for client-side rendered (CSR) or static site generated (SSG) Nuxt applications. If you're using server-side rendering (SSR), you might need a different approach to achieve a similar effect. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai3d ago
<@1079709612078534676> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
Adnan Erlansyah
Adnan ErlansyahOP3d ago
@kapa.ai it's still not working, I can't see the splash screen when visited the app for the first time.
kapa.ai
kapa.ai3d ago
Let me check the knowledge base for you again. One moment! :books: ---------------------- I apologize that the splash screen is not working as expected. Let's troubleshoot this issue step by step: 1. First, make sure you have set ssr: false in your nuxt.config.ts file. The SPA loading template only works for client-side rendered applications. Here's how to configure it:
export default defineNuxtConfig({
ssr: false
})

export default defineNuxtConfig({
ssr: false
})

Nuxt Configuration Reference 2. Ensure that you have placed the spa-loading-template.html file in the correct location, which is in the app directory of your Nuxt project. 3. By default, Nuxt uses null for the spaLoadingTemplate configuration. You might need to explicitly set it to true in your nuxt.config.ts:
export default defineNuxtConfig({
ssr: false,
spaLoadingTemplate: true
})

export default defineNuxtConfig({
ssr: false,
spaLoadingTemplate: true
})

4. If you're using Nuxt 3.8 or later, there's a new configuration option for the location of the SPA loading template. You can try setting it to body:
export default defineNuxtConfig({
experimental: {
spaLoadingTemplateLocation: 'body'
}
})

export default defineNuxtConfig({
experimental: {
spaLoadingTemplateLocation: 'body'
}
})

Nuxt Documentation on spaLoadingTemplateLocation 5. Make sure your spa-loading-template.html file contains visible content. Here's a simple example:
<div class="loader">Loading...</div>
<style>
.loader {
display: block;
position: fixed;
z-index: 1031;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
</style>

<div class="loader">Loading...</div>
<style>
.loader {
display: block;
position: fixed;
z-index: 1031;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
</style>

Nuxt Configuration Reference 6. If you're still not seeing the splash screen, it might be because the app is loading too quickly. You can artificially delay the app initialization for testing purposes by adding a mounted hook in your app.vue:
<script setup>
onMounted(() => {
setTimeout(() => {
// Your initialization code here
}, 3000) // 3 seconds delay
})
</script>

<script setup>
onMounted(() => {
setTimeout(() => {
// Your initialization code here
}, 3000) // 3 seconds delay
})
</script>

If none of these steps solve the issue, it's possible that there might be a bug or limitation in the current version of Nuxt you're using. In that case, I recommend reporting the issue to the Nuxt team with a minimal reproduction of the problem. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai3d ago
<@1079709612078534676> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
Adnan Erlansyah
Adnan ErlansyahOP3d ago
@kapa.ai how about if I won't to set the ssr to false because most of all the ssr of my pages are true. It needs ssr to support SEO.
kapa.ai
kapa.ai3d ago
Let me check the knowledge base for you again. One moment! :books: ---------------------- I understand your concern about maintaining SSR for SEO purposes. You're right that setting ssr: false globally would not be ideal if most of your pages require server-side rendering for SEO. In this case, we need to approach the splash screen differently. Here are a few alternatives you can consider: 1. Use a client-side loading component: Instead of using the SPA loading template, you can create a custom loading component that acts as a splash screen. This component would be rendered on the client side after the initial server-side render.
<!-- components/SplashScreen.vue -->
<template>
<div v-if="showSplash" class="splash-screen">
<!-- Your splash screen content -->
</div>
</template>

<script setup>
import { ref, onMounted } from 'vue'

const showSplash = ref(true)

onMounted(() => {
// Hide splash screen after a delay
setTimeout(() => {
showSplash.value = false
}, 3000) // Adjust time as needed
})
</script>

<!-- components/SplashScreen.vue -->
<template>
<div v-if="showSplash" class="splash-screen">
<!-- Your splash screen content -->
</div>
</template>

<script setup>
import { ref, onMounted } from 'vue'

const showSplash = ref(true)

onMounted(() => {
// Hide splash screen after a delay
setTimeout(() => {
showSplash.value = false
}, 3000) // Adjust time as needed
})
</script>

Then, include this component in your app.vue:
<template>
<div>
<SplashScreen />
<NuxtPage />
</div>
</template>

<template>
<div>
<SplashScreen />
<NuxtPage />
</div>
</template>

2. Use Nuxt's client-only component: Wrap your splash screen in a <ClientOnly> component to ensure it only renders on the client side:
<template>
<div>
<ClientOnly>
<SplashScreen />
</ClientOnly>
<NuxtPage />
</div>
</template>

<template>
<div>
<ClientOnly>
<SplashScreen />
</ClientOnly>
<NuxtPage />
</div>
</template>

3. Leverage route middleware: You can use route middleware to show the splash screen only on the first visit. This approach allows you to maintain SSR while still showing a splash screen:
// middleware/splash.global.ts
export default defineNuxtRouteMiddleware((to, from) => {
if (process.client && !from.name) {
// First client-side navigation
useState('showSplash', () => true)
}
})

// middleware/splash.global.ts
export default defineNuxtRouteMiddleware((to, from) => {
if (process.client && !from.name) {
// First client-side navigation
useState('showSplash', () => true)
}
})

Then in your app.vue:
<template>
<div>
<SplashScreen v-if="showSplash" />
<NuxtPage />
</div>
</template>

<script setup>
const showSplash = useState('showSplash', () => false)

onMounted(() => {
if (showSplash.value) {
setTimeout(() => {
showSplash.value = false
}, 3000) // Adjust time as needed
}
})
</script>

<template>
<div>
<SplashScreen v-if="showSplash" />
<NuxtPage />
</div>
</template>

<script setup>
const showSplash = useState('showSplash', () => false)

onMounted(() => {
if (showSplash.value) {
setTimeout(() => {
showSplash.value = false
}, 3000) // Adjust time as needed
}
})
</script>

4. Use dynamic rendering: If you want to show the splash screen only for users and not for search engine bots, you can use dynamic rendering. This approach is described in the Nuxt 3 Dynamic Rendering video. It allows you to serve different content to users and crawlers, potentially showing the splash screen only to real users. Remember, while these methods allow you to keep SSR enabled, they may still impact the initial load time of your application. Be sure to optimize your splash screen and consider the user experience when implementing this feature. Nuxt 3 Documentation on ClientOnly Nuxt 3 Documentation on Route Middleware These approaches should allow you to implement a splash screen effect while maintaining SSR for most of your pages, thus supporting your SEO requirements. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai3d ago
<@1079709612078534676> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
Adnan Erlansyah
Adnan ErlansyahOP3d ago
@kapa.ai how about use method callOnce from NuxtJS 3?
kapa.ai
kapa.ai3d ago
Let me check the knowledge base for you again. One moment! :books: ---------------------- The callOnce utility in Nuxt 3 is indeed a good option for implementing a splash screen effect while maintaining SSR. This method is designed to execute a given function or block of code only once during server-side rendering and client-side navigation, which aligns well with your requirement for a splash screen that appears only on the first visit. Here's how you can use callOnce to implement a splash screen: 1. First, create a state to control the visibility of your splash screen:
<script setup>
const showSplash = useState('showSplash', () => true)
</script>
<script setup>
const showSplash = useState('showSplash', () => true)
</script>
2. Then, use callOnce in your app.vue to set up the splash screen logic:
<template>
<div>
<div v-if="showSplash" class="splash-screen">
<!-- Your splash screen content -->
</div>
<NuxtPage />
</div>
</template>

<script setup>
const showSplash = useState('showSplash', () => true)

await callOnce(async () => {
// Simulate loading time
await new Promise(resolve => setTimeout(resolve, 3000))

// Hide splash screen
showSplash.value = false
})
</script>
<template>
<div>
<div v-if="showSplash" class="splash-screen">
<!-- Your splash screen content -->
</div>
<NuxtPage />
</div>
</template>

<script setup>
const showSplash = useState('showSplash', () => true)

await callOnce(async () => {
// Simulate loading time
await new Promise(resolve => setTimeout(resolve, 3000))

// Hide splash screen
showSplash.value = false
})
</script>
This approach has several advantages: 1. It works with SSR enabled, so you don't have to compromise on SEO. 2. The splash screen will only be shown once per session, even during client-side navigation. 3. It's simple to implement and doesn't require additional middleware or components. However, there are a couple of things to keep in mind: 1. The callOnce function is available since Nuxt v3.9, so make sure you're using a compatible version. 2. Be cautious about what you put inside callOnce. As the documentation states, "Note that callOnce doesn't return anything. You should use useAsyncData or useFetch if you want to do data fetching during SSR." If you need to re-run the splash screen during navigation, you can use the new mode: 'navigation' option introduced in a recent update:
<script setup>
await callOnce(async () => {
// Your splash screen logic
}, { mode: 'navigation' })
</script>
<script setup>
await callOnce(async () => {
// Your splash screen logic
}, { mode: 'navigation' })
</script>
This will allow the splash screen to appear not just on the initial load, but also during subsequent navigations. Nuxt 3 Documentation on callOnce Remember to keep your splash screen lightweight to avoid negatively impacting your app's performance and user experience. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai3d ago
<@1079709612078534676> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
Adnan Erlansyah
Adnan ErlansyahOP3d ago
@kapa.ai the splash screen is still not shown.
kapa.ai
kapa.ai3d ago
Let me check the knowledge base for you again. One moment! :books: ---------------------- I apologize that the splash screen is still not showing up. Let's troubleshoot this issue further. Based on the information provided, there could be a few reasons why the splash screen isn't appearing. Here are some steps to check and potential solutions: 1. Verify Nuxt version: Make sure you're using Nuxt 3.9 or later, as callOnce was introduced in this version. You can check your version in the package.json file or by running npm list nuxt in your project directory. 2. Check the implementation: Ensure that your app.vue file looks similar to this:
<template>
<div>
<div v-if="showSplash" class="splash-screen">
<!-- Your splash screen content -->
Loading...
</div>
<NuxtPage />
</div>
</template>

<script setup>
const showSplash = useState('showSplash', () => true)

await callOnce(async () => {
// Simulate loading time
await new Promise(resolve => setTimeout(resolve, 3000))

// Hide splash screen
showSplash.value = false
})
</script>

<style scoped>
.splash-screen {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: #fff;
display: flex;
justify-content: center;
align-items: center;
z-index: 9999;
}
</style>

<template>
<div>
<div v-if="showSplash" class="splash-screen">
<!-- Your splash screen content -->
Loading...
</div>
<NuxtPage />
</div>
</template>

<script setup>
const showSplash = useState('showSplash', () => true)

await callOnce(async () => {
// Simulate loading time
await new Promise(resolve => setTimeout(resolve, 3000))

// Hide splash screen
showSplash.value = false
})
</script>

<style scoped>
.splash-screen {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: #fff;
display: flex;
justify-content: center;
align-items: center;
z-index: 9999;
}
</style>

3. Debug with console logs: Add console logs to verify if callOnce is being executed:
<script setup>
const showSplash = useState('showSplash', () => true)

await callOnce(async () => {
console.log('callOnce executed')
await new Promise(resolve => setTimeout(resolve, 3000))
console.log('Hiding splash screen')
showSplash.value = false
})
</script>

<script setup>
const showSplash = useState('showSplash', () => true)

await callOnce(async () => {
console.log('callOnce executed')
await new Promise(resolve => setTimeout(resolve, 3000))
console.log('Hiding splash screen')
showSplash.value = false
})
</script>

4. Try using onMounted hook: If the issue persists, you can try using the onMounted hook instead:
<script setup>
import { onMounted } from 'vue'

const showSplash = useState('showSplash', () => true)

onMounted(() => {
setTimeout(() => {
showSplash.value = false
}, 3000)
})
</script>

<script setup>
import { onMounted } from 'vue'

const showSplash = useState('showSplash', () => true)

onMounted(() => {
setTimeout(() => {
showSplash.value = false
}, 3000)
})
</script>

5. Check for CSS conflicts: Ensure that there are no CSS rules overriding your splash screen styles. You might want to increase the z-index or check for any conflicting styles. 6. Clear browser cache: Sometimes, cached files can interfere with new implementations. Try clearing your browser cache and hard reloading the page. 7. Verify in different browsers: Test your application in different browsers to rule out browser-specific issues. If none of these solutions work, it might be helpful to create a minimal reproduction of the issue and share it on the Nuxt GitHub repository or the Nuxt Discord community for further assistance. Remember, the callOnce utility is designed to run the code only once during server-side rendering and client-side navigation. If you're not seeing the splash screen at all, it might be worth considering a different approach, such as using a client-only component or a more traditional loading screen implementation. Nuxt 3 Documentation on callOnce ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai3d ago
<@1079709612078534676> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
Adnan Erlansyah
Adnan ErlansyahOP2d ago
@kapa.ai is there another way to do it?
kapa.ai
kapa.ai2d ago
Let me check the knowledge base for you again. One moment! :books: ---------------------- Yes, there are alternative ways to implement a splash screen effect in Nuxt 3 while maintaining SSR support. Here are a couple of other approaches you can try: 1. Using a custom plugin and Nuxt hooks: Create a new plugin file, for example, plugins/splash-screen.js:
export default defineNuxtPlugin((nuxtApp) => {
const showSplash = useState('showSplash', () => true)

nuxtApp.hook('app:mounted', () => {
setTimeout(() => {
showSplash.value = false
}, 3000) // Adjust the delay as needed
})
})
export default defineNuxtPlugin((nuxtApp) => {
const showSplash = useState('showSplash', () => true)

nuxtApp.hook('app:mounted', () => {
setTimeout(() => {
showSplash.value = false
}, 3000) // Adjust the delay as needed
})
})
Then, in your app.vue:
<template>
<div>
<div v-if="showSplash" class="splash-screen">
<!-- Your splash screen content -->
</div>
<NuxtPage />
</div>
</template>

<script setup>
const showSplash = useState('showSplash', () => true)
</script>
<template>
<div>
<div v-if="showSplash" class="splash-screen">
<!-- Your splash screen content -->
</div>
<NuxtPage />
</div>
</template>

<script setup>
const showSplash = useState('showSplash', () => true)
</script>
2. Using useAsyncData in your app.vue:
<template>
<div>
<div v-if="pending" class="splash-screen">
<!-- Your splash screen content -->
</div>
<NuxtPage />
</div>
</template>

<script setup>
const { pending } = useAsyncData('splash', async () => {
await new Promise(resolve => setTimeout(resolve, 3000)) // Simulating loading
})
</script>
<template>
<div>
<div v-if="pending" class="splash-screen">
<!-- Your splash screen content -->
</div>
<NuxtPage />
</div>
</template>

<script setup>
const { pending } = useAsyncData('splash', async () => {
await new Promise(resolve => setTimeout(resolve, 3000)) // Simulating loading
})
</script>
This approach uses the pending state from useAsyncData to control the visibility of the splash screen. 3. Using a custom loading component: Create a new component, components/SplashScreen.vue:
<template>
<div v-if="show" class="splash-screen">
<!-- Your splash screen content -->
</div>
</template>

<script setup>
const show = ref(true)

onMounted(() => {
setTimeout(() => {
show.value = false
}, 3000)
})
</script>
<template>
<div v-if="show" class="splash-screen">
<!-- Your splash screen content -->
</div>
</template>

<script setup>
const show = ref(true)

onMounted(() => {
setTimeout(() => {
show.value = false
}, 3000)
})
</script>
Then in your app.vue:
<template>
<div>
<ClientOnly>
<SplashScreen />
</ClientOnly>
<NuxtPage />
</div>
</template>
<template>
<div>
<ClientOnly>
<SplashScreen />
</ClientOnly>
<NuxtPage />
</div>
</template>
This approach uses the <ClientOnly> component to ensure the splash screen only renders on the client side, avoiding any SSR conflicts. These methods should work with SSR enabled and provide alternative ways to implement a splash screen effect in your Nuxt 3 application. Remember to adjust the timing and content of the splash screen to suit your specific needs. Nuxt 3 Documentation on Plugins Nuxt 3 Documentation on useAsyncData Nuxt 3 Documentation on ClientOnly ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai2d ago
<@1079709612078534676> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
Adnan Erlansyah
Adnan ErlansyahOP2d ago
@kapa.ai how about using this way. So I make a composable to set the visit check if it's the first time of user access the page then set it then check if user has visited the page or not. then when the browser is closed or maybe menu tab of browser is closed then remove the visit.
export default function useSplash() {

const setVisitCheck = async () => (useCookie("_vc", { path: "/" }).value = true.toString())
const getVisitCheck = (): string | null => useCookie("_vc").value || null;
const rmVisitCheck = async () => (useCookie("_vc").value = null);

return {
setVisitCheck,
getVisitCheck,
rmVisitCheck
}

}
export default function useSplash() {

const setVisitCheck = async () => (useCookie("_vc", { path: "/" }).value = true.toString())
const getVisitCheck = (): string | null => useCookie("_vc").value || null;
const rmVisitCheck = async () => (useCookie("_vc").value = null);

return {
setVisitCheck,
getVisitCheck,
rmVisitCheck
}

}
kapa.ai
kapa.ai2d ago
Let me check the knowledge base for you again. One moment! :books: ---------------------- Your approach using a composable function with cookies is a valid and practical way to implement a splash screen effect in Nuxt 3. This method allows you to maintain the splash screen state across page reloads while still supporting SSR. Let's break down your implementation and suggest some improvements:
export default function useSplash() {
const setVisitCheck = async () => (useCookie("_vc", { path: "/" }).value = true.toString())
const getVisitCheck = (): string | null => useCookie("_vc").value || null;
const rmVisitCheck = async () => (useCookie("_vc").value = null);

return {
setVisitCheck,
getVisitCheck,
rmVisitCheck
}
}
export default function useSplash() {
const setVisitCheck = async () => (useCookie("_vc", { path: "/" }).value = true.toString())
const getVisitCheck = (): string | null => useCookie("_vc").value || null;
const rmVisitCheck = async () => (useCookie("_vc").value = null);

return {
setVisitCheck,
getVisitCheck,
rmVisitCheck
}
}
This approach is good because: 1. It uses Nuxt's built-in useCookie composable, which is SSR-friendly. 2. It provides methods to set, get, and remove the visit check, giving you flexibility in managing the splash screen state. However, there are a few things to consider and potential improvements: 1. Cookie Options: You're setting the path option for setVisitCheck, but not for getVisitCheck and rmVisitCheck. It's better to be consistent:
const cookieOptions = { path: "/" };
const setVisitCheck = () => useCookie("_vc", cookieOptions).value = "true";
const getVisitCheck = () => useCookie("_vc", cookieOptions).value || null;
const rmVisitCheck = () => useCookie("_vc", cookieOptions).value = null;
const cookieOptions = { path: "/" };
const setVisitCheck = () => useCookie("_vc", cookieOptions).value = "true";
const getVisitCheck = () => useCookie("_vc", cookieOptions).value || null;
const rmVisitCheck = () => useCookie("_vc", cookieOptions).value = null;
2. Type Safety: You can improve type safety by using a boolean instead of a string:
const setVisitCheck = () => useCookie<boolean>("_vc", cookieOptions).value = true;
const getVisitCheck = () => useCookie<boolean>("_vc", cookieOptions).value ?? null;
const setVisitCheck = () => useCookie<boolean>("_vc", cookieOptions).value = true;
const getVisitCheck = () => useCookie<boolean>("_vc", cookieOptions).value ?? null;
3. Automatic Removal: To remove the cookie when the browser or tab is closed, you can set the cookie with no expiration date:
const cookieOptions = { path: "/", sameSite: "strict" };
const cookieOptions = { path: "/", sameSite: "strict" };
This way, the cookie will be a session cookie and will be automatically removed when the browser is closed. To use this composable in your application:
<template>
<div>
<div v-if="showSplash" class="splash-screen">
<!-- Your splash screen content -->
</div>
<NuxtPage />
</div>
</template>

<script setup>
const { setVisitCheck, getVisitCheck } = useSplash();
const showSplash = ref(true);

onMounted(async () => {
if (!getVisitCheck()) {
await setVisitCheck();
// Show splash screen for 3 seconds
setTimeout(() => {
showSplash.value = false;
}, 3000);
} else {
showSplash.value = false;
}
});
</script>
<template>
<div>
<div v-if="showSplash" class="splash-screen">
<!-- Your splash screen content -->
</div>
<NuxtPage />
</div>
</template>

<script setup>
const { setVisitCheck, getVisitCheck } = useSplash();
const showSplash = ref(true);

onMounted(async () => {
if (!getVisitCheck()) {
await setVisitCheck();
// Show splash screen for 3 seconds
setTimeout(() => {
showSplash.value = false;
}, 3000);
} else {
showSplash.value = false;
}
});
</script>
This implementation using useCookie is a good approach because it's compatible with SSR and provides a way to persist the splash screen state across page reloads. It's also more flexible than using callOnce as it allows you to control when and how the splash screen is shown or hidden. Nuxt 3 Documentation on useCookie Remember to adjust the timing and content of your splash screen to provide the best user experience for your specific application. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai2d ago
<@1079709612078534676> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
Adnan Erlansyah
Adnan ErlansyahOP2d ago
@kapa.ai but it still displaying the splash screen after I refreshed the browser, it should be run once.
kapa.ai
kapa.ai2d ago
Let me check the knowledge base for you again. One moment! :books: ---------------------- I apologize for the confusion. You're right that the splash screen should only appear once, even after refreshing the browser. Let's modify the approach to ensure it runs only once per session. Here's an improved version of the useSplash composable:
export default function useSplash() {
const cookieOptions = {
path: "/",
maxAge: 60 * 60 * 24, // 1 day
sameSite: 'strict' as const
};

const setVisitCheck = () => useCookie("_vc", cookieOptions).value = true;
const getVisitCheck = () => useCookie<boolean>("_vc", cookieOptions).value ?? false;

return {
setVisitCheck,
getVisitCheck
}
}
export default function useSplash() {
const cookieOptions = {
path: "/",
maxAge: 60 * 60 * 24, // 1 day
sameSite: 'strict' as const
};

const setVisitCheck = () => useCookie("_vc", cookieOptions).value = true;
const getVisitCheck = () => useCookie<boolean>("_vc", cookieOptions).value ?? false;

return {
setVisitCheck,
getVisitCheck
}
}
Now, let's use this composable in your app.vue or the component where you want to show the splash screen:
<template>
<div>
<div v-if="showSplash" class="splash-screen">
<!-- Your splash screen content -->
</div>
<NuxtPage />
</div>
</template>

<script setup>
const { setVisitCheck, getVisitCheck } = useSplash();
const showSplash = ref(!getVisitCheck());

onMounted(() => {
if (!getVisitCheck()) {
setVisitCheck();
// Show splash screen for 3 seconds
setTimeout(() => {
showSplash.value = false;
}, 3000);
}
});
</script>
<template>
<div>
<div v-if="showSplash" class="splash-screen">
<!-- Your splash screen content -->
</div>
<NuxtPage />
</div>
</template>

<script setup>
const { setVisitCheck, getVisitCheck } = useSplash();
const showSplash = ref(!getVisitCheck());

onMounted(() => {
if (!getVisitCheck()) {
setVisitCheck();
// Show splash screen for 3 seconds
setTimeout(() => {
showSplash.value = false;
}, 3000);
}
});
</script>
This implementation should solve the issue of the splash screen appearing after refreshing the browser. Here's what's happening: 1. We set a maxAge for the cookie, so it persists across browser refreshes. 2. getVisitCheck() now returns a boolean, defaulting to false if the cookie doesn't exist. 3. We initialize showSplash based on the inverse of getVisitCheck(). 4. In the onMounted hook, we only show the splash screen and set the cookie if getVisitCheck() is false. This approach ensures that: - The splash screen only shows on the first visit. - The state persists across refreshes. - The cookie expires after a day (you can adjust this as needed). If you're still experiencing issues, make sure to: 1. Clear your browser cookies before testing. 2. Check if there are any other scripts or components that might be interfering with the splash screen logic. Nuxt 3 Documentation on useCookie Remember, this solution uses client-side logic in the onMounted hook, which ensures it works correctly with SSR while still providing the desired splash screen behavior. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai2d ago
<@1079709612078534676> Kapa.ai is still learning and improving, please let me know how I did by reacting below.

Did you find this page helpful?