-
Notifications
You must be signed in to change notification settings - Fork 144
/
app.vue
137 lines (122 loc) · 3.6 KB
/
app.vue
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
<script setup lang="ts">
import { debounce } from 'perfect-debounce'
import type { ParsedContent } from '@nuxt/content'
import './styles/twoslash.css'
const search = ref(null)
const colorMode = useColorMode()
const { headerLinks, searchGroups, searchLinks } = useNavigation()
const color = computed(() => colorMode.value === 'dark' ? '#020420' : 'white')
const { data: navigation } = await useLazyAsyncData('navigation', () => fetchContentNavigation(), { default: () => [] })
const { data: files } = useLazyFetch<ParsedContent[]>('/api/search.json', {
default: () => [],
server: false
})
useHead({
titleTemplate: title => title ? `${title} · Nuxt` : 'Nuxt: The Intuitive Web Framework',
meta: [
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
{ key: 'theme-color', name: 'theme-color', content: color }
],
link: [
{ rel: 'icon', type: 'image/png', href: '/icon.png' }
],
htmlAttrs: {
lang: 'en'
}
})
useSeoMeta({
ogSiteName: 'Nuxt',
ogType: 'website',
twitterCard: 'summary_large_image',
twitterSite: 'nuxt_js'
})
watch(() => search.value?.commandPaletteRef?.query, debounce((query: string) => {
if (!query) {
return
}
useTrackEvent('Search', { props: { query: `${query} - ${search.value?.commandPaletteRef.results.length} results` } })
}, 500))
// Provide
provide('navigation', navigation)
const route = useRoute()
const heroBackgroundClass = computed(() => route.meta?.heroBackground || '')
const { isLoading } = useLoadingIndicator()
const appear = ref(false)
const appeared = ref(false)
onMounted(() => {
setTimeout(() => {
appear.value = true
setTimeout(() => {
appeared.value = true
}, 1000)
}, 0)
})
</script>
<template>
<div>
<NuxtLoadingIndicator />
<AppBanner
id="nuxt-tips"
to="https://michaelnthiessen.com/nuxt-tips-collection?aff=J0Emk"
>
<div class="flex items-center gap-1">
<UIcon
name="i-ph-magic-wand"
class="w-5 h-5 flex-shrink-0 pointer-events-none hidden lg:inline-block mr-1"
/>
<span>Learn Nuxt with a Collection of 100+ Tips!</span>
<UButton
label="Learn more"
color="white"
trailing-icon="i-ph-arrow-right"
size="2xs"
class="rounded-full ml-1"
/>
</div>
</AppBanner>
<!-- <AppBanner
id="nuxt-certification-early-bird-launch"
to="https://certification.nuxt.com"
>
<div class="flex items-center gap-2">
<UIcon
name="i-ph-medal"
class="w-5 h-5 flex-shrink-0 pointer-events-none"
/>
<span>The <span class="font-semibold">Nuxt Certification Program</span> by VueSchool is out!</span>
<UButton
color="white"
trailing-icon="i-ph-arrow-right"
size="2xs"
class="rounded-full"
>
Register
</UButton>
</div>
</AppBanner> -->
<AppHeader :links="headerLinks" />
<UMain class="relative">
<HeroBackground
class="absolute w-full top-[1px] transition-all text-primary flex-shrink-0"
:class="[
isLoading ? 'animate-pulse' : (appear ? 'opacity-100' : 'opacity-0'),
appeared ? 'duration-[400ms]': 'duration-1000',
heroBackgroundClass
]"
/>
<NuxtPage />
</UMain>
<AppFooter />
<ClientOnly>
<UContentSearch
ref="search"
:files="files"
:navigation="navigation[0]?.children"
:groups="searchGroups"
:links="searchLinks"
:fuse="{ resultLimit: 13 }"
/>
<UNotifications />
</ClientOnly>
</div>
</template>