From ebe72907a4d01e4f40b487399931a738ddfb5e98 Mon Sep 17 00:00:00 2001 From: Ruslan Bakiev <572431+veikab@users.noreply.github.com> Date: Sat, 14 Mar 2026 11:01:53 +0700 Subject: [PATCH] fix: show immediate full-screen loader during route navigation --- app/app.vue | 32 +++++++++++++++++++++- app/plugins/route-loading.client.ts | 41 +++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+), 1 deletion(-) create mode 100644 app/plugins/route-loading.client.ts diff --git a/app/app.vue b/app/app.vue index a53f009..86aff55 100644 --- a/app/app.vue +++ b/app/app.vue @@ -1,11 +1,29 @@ + + diff --git a/app/plugins/route-loading.client.ts b/app/plugins/route-loading.client.ts new file mode 100644 index 0000000..cfe0457 --- /dev/null +++ b/app/plugins/route-loading.client.ts @@ -0,0 +1,41 @@ +export default defineNuxtPlugin((nuxtApp) => { + const routeLoading = useState('route-loading', () => false) + let hideTimer: ReturnType | null = null + + const show = () => { + if (hideTimer) { + clearTimeout(hideTimer) + hideTimer = null + } + routeLoading.value = true + } + + const hide = () => { + if (hideTimer) { + clearTimeout(hideTimer) + } + // Small delay to prevent flicker on very fast routes. + hideTimer = setTimeout(() => { + routeLoading.value = false + hideTimer = null + }, 120) + } + + nuxtApp.$router.beforeEach((_to, _from, next) => { + show() + next() + }) + + nuxtApp.$router.afterEach(() => { + hide() + }) + + nuxtApp.$router.onError(() => { + hide() + }) + + nuxtApp.hook('page:finish', () => { + hide() + }) +}) +