chore(docs): improvements (#655)

Co-authored-by: Sylvain Marroufin <marroufin.sylvain@gmail.com>
Co-authored-by: Pooya Parsa <pyapar@gmail.com>
This commit is contained in:
Sébastien Chopin 2021-10-11 14:57:54 +02:00 committed by GitHub
parent 2f5938c7b5
commit 18cf0ba865
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
134 changed files with 5291 additions and 2064 deletions

View File

@ -3,3 +3,4 @@ node_modules
schema
**/*.tmpl.*
sw.js
docs

View File

@ -7,24 +7,23 @@ Please carefully read the contribution docs before creating a pull request
### 🔗 Linked issue
<!-- ❗ Please ensure there is an open issue -->
#...
<!-- Please ensure there is an open issue and mention it's number as #123 -->
### ❓ Type of change
<!-- What types of changes does your code introduce? Put `x's in all the boxes that apply: -->
<!-- What types of changes does your code introduce? Put `x's in all the boxes -->
- [ ] Documentation (updates to the documentation or readme)
- [ ] Bug fix (a non-breaking change that fixes an issue)
- [ ] Enhancement (improving an existing functionality like performance)
- [ ] New feature (a non-breaking change that adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to change)
- [ ] 📖 Documentation (updates to the documentation or readme)
- [ ] 🐞 Bug fix (a non-breaking change that fixes an issue)
- [ ] 👌 Enhancement (improving an existing functionality like performance)
- [ ] New feature (a non-breaking change that adds functionality)
- [ ] ⚠️ Breaking change (fix or feature that would cause existing functionality to change)
### 📚 Description
<!-- Describe your changes in detail -->
<!-- Why is this change required? What problem does it solve? -->
<!-- If it resolves an open issue, please link to the issue here. For example "Resolves: #1337" -->
<!-- If it resolves an open issue, please link to the issue here. For example "Resolves #1337" -->
### 📝 Checklist

View File

@ -44,17 +44,28 @@ Welcome to Nuxt3 repository ✨
</tbody>
</table>
## 👀 Private beta
We are currently in private beta in order to stabilize the framework before opening to the whole community.
Please take a look at the [beta discussion](https://github.com/nuxt/framework/discussions/434) for further information.
## 💻 Development
- Clone repository
- Ensure you have the latest LTS version of Node.js installed
- Install dependencies with `yarn install`
- Run `yarn stub` to activate passive development
- Open playground with `yarn play`
- Install dependencies with `npx yarn install`
- Run `npx yarn stub` to activate passive development
- Open playground with `npx yarn play`
Learn more about in our documentation on [how to contribute to Nuxt](https://v3.nuxtjs.org/community/contribution).
## 📖 Documentation
We are using [Docus](https://nuxtlabs.com/docus) for documentation (*It is planned to be open sourced it in the following weeks*).
We recommend to install the [Docus extension](https://marketplace.visualstudio.com/items?itemName=NuxtLabs.docus) for VS Code.
- Go into the docs directory: `cd docs`
- Install docs dependencies with `npx yarn install`
- Run `npx yarn dev` to start Docus in development mode
The pages are generated from [docs/content/](./docs/content), you can start editing them to start helping us on documenting Nuxt 3 💚
## License
[MIT](https://github.com/nuxt/nuxt.js/blob/dev/LICENSE)

1
docs/.gitignore vendored
View File

@ -1,2 +1 @@
5.config
schema

26
docs/assets/nuxt.css Normal file
View File

@ -0,0 +1,26 @@
:root {
--header-height: theme('spacing.14');
--docs-scroll-margin-block: calc(var(--header-height) + 4rem);
--blogpost-scroll-margin-block: calc(var(--header-height));
}
@screen md {
:root {
--header-height: theme('spacing.18');
--blogpost-scroll-margin-block: calc(var(--header-height) - 0.5rem);
}
}
@screen xl {
:root {
--docs-scroll-margin-block: calc(var(--header-height) + 1rem);
}
}
button:focus-visible, div:focus-visible, a:focus-visible {
/* remove default focus style */
outline: none;
/* custom focus style */
border-radius: 2px;
box-shadow: 0 0 0 2px #00DC82;
}

View File

@ -1,25 +0,0 @@
<template>
<svg viewBox="0 0 221 65" fill="none" xmlns="http://www.w3.org/2000/svg" @click="home">
<path d="M76.333 20.5005H82.8185L96.5631 42.4764V20.5005H102.55V51.6393H96.1087L82.3198 29.7091V51.6393H76.333V20.5005Z" fill="currentColor" />
<path d="M129.311 51.6393H123.732V48.1611C122.462 50.6089 119.877 51.9871 116.612 51.9871C111.441 51.9871 108.083 48.3393 108.083 43.0894V29.2178H113.662V41.9416C113.662 45.0111 115.568 47.1459 118.425 47.1459C121.555 47.1459 123.732 44.7437 123.732 41.4524V29.2178H129.311V51.6393Z" fill="currentColor" />
<path d="M148.724 51.2848L143.372 43.811L138.019 51.2848H132.076L140.333 39.5849L132.712 28.8633H138.79L143.372 35.3154L147.906 28.8633H154.031L146.364 39.5849L154.62 51.2848H148.724Z" fill="currentColor" />
<path d="M165.96 22.4565V29.2173H172.311V33.7999H165.96V44.9302C165.96 45.304 166.111 45.6626 166.381 45.9271C166.65 46.1916 167.015 46.3405 167.397 46.3411H172.311V51.6302H168.636C163.646 51.6302 160.381 48.7824 160.381 43.8042V33.8043H155.891V29.2173H158.708C160.022 29.2173 160.787 28.45 160.787 27.1804V22.4565H165.96Z" fill="currentColor" />
<path d="M186.374 44.5872V20.5005H192.359V42.7416C192.359 48.748 189.411 51.6393 184.422 51.6393H177.455V46.3502H184.577C185.053 46.3502 185.511 46.1645 185.848 45.8339C186.185 45.5032 186.374 45.0548 186.374 44.5872" fill="currentColor" />
<path d="M195.945 41.1847H201.708C202.027 44.6629 204.386 46.8781 208.196 46.8781C211.598 46.8781 213.959 45.5455 213.959 42.7869C213.959 36.113 196.892 40.739 196.892 28.8174C196.896 23.7023 201.387 20.1479 207.839 20.1479C214.553 20.1479 219.088 23.9283 219.365 29.7565H213.633C213.363 27.0435 211.195 25.2196 207.828 25.2196C204.698 25.2196 202.748 26.6435 202.748 28.8218C202.748 35.7174 220.037 30.5609 220.037 42.7021C220.037 48.4846 215.182 51.9998 208.198 51.9998C200.986 51.9998 196.269 47.7281 195.952 41.189" fill="currentColor" />
<path fill-rule="evenodd" clip-rule="evenodd" d="M29.7513 14.261C28.0767 11.3817 23.8903 11.3817 22.2157 14.261L3.96535 45.641C2.29077 48.5204 4.38399 52.1195 7.73316 52.1195H21.9804C20.5493 50.8688 20.0193 48.7051 21.1023 46.8487L34.9243 23.1556L29.7513 14.261Z" fill="#80EEC0" />
<path d="M41.3151 21.1443C42.701 18.7885 46.1656 18.7885 47.5515 21.1443L62.6552 46.8188C64.0411 49.1746 62.3088 52.1194 59.537 52.1194H29.3296C26.5579 52.1194 24.8255 49.1746 26.2114 46.8188L41.3151 21.1443Z" fill="#00DC82" />
</svg>
</template>
<script>
export default {
methods: {
home () {
if (this.$route.path === '/') {
// scroll to top
window.scrollTo(0, 0)
}
}
}
}
</script>

View File

@ -0,0 +1,118 @@
<template>
<aside class="fixed z-50 lg:z-0 lg:static">
<div class="h-full overflow-auto pointer-events-none lg:overflow-visible">
<!-- scrim -->
<Transition name="fade">
<div
v-if="$menu.visible.value"
class="fixed top-0 left-0 z-0 w-full h-full pointer-events-auto d-bg-header d-blur-header lg:hidden"
@click.stop="$menu.toggle"
/>
</Transition>
<!-- Desktop aside -->
<div
class="
hidden
lg:block
fixed
top-0
left-0
overflow-auto
pointer-events-auto
min-h-fill-available
h-screen
sticky
top-header
w-60
"
>
<div class="w-auto h-full overflow-auto">
<AsideNavigation />
</div>
</div>
<!-- Mobile aside -->
<Transition name="slide-from-left-to-left">
<div
v-show="$menu.visible.value"
class="
lg:hidden
fixed
top-0
left-0
w-auto
h-full
overflow-auto
pointer-events-auto
min-h-fill-available
border-r
dark:border-sky-darker
!w-base
"
>
<div class="w-auto h-full overflow-auto d-bg-header">
<div
class="flex items-center justify-between w-full px-0.5 sm:px-2 h-header d-aside-header-bg"
>
<button
class="transition-colors duration-200 d-secondary-text hover:d-secondary-text-hover focus:outline-none"
aria-label="backButton"
@click.stop="mobileBack"
>
<IconArrowLeft v-if="!mobileMainNav && layout.aside" class="p-3 w-12 h-12" />
<IconClose v-else class="p-3 w-12 h-12" />
</button>
<div class="flex items-center h-header space-x-1">
<GitHubButton />
<TwitterButton />
<ColorSwitcher padding="p-3" />
</div>
</div>
<AsideNavigation v-if="!mobileMainNav && layout.aside" />
<AsideHeaderNavigation v-else :links="links" />
</div>
</div>
</Transition>
</div>
</aside>
</template>
<script lang="ts">
import { defineComponent, useContext, ref, watch } from '@nuxtjs/composition-api'
export default defineComponent({
props: {
links: {
type: Array,
default: () => []
}
},
setup () {
const { $docus, $menu } = useContext()
const mobileMainNav = ref(!$docus.layout.value.aside)
watch($menu.visible, (value, old) => {
if (value && !old && $docus.layout.value.aside) {
mobileMainNav.value = false
}
})
function mobileBack () {
if (!mobileMainNav.value) {
mobileMainNav.value = true
} else {
$menu.close()
}
}
return {
mobileMainNav,
mobileBack,
layout: $docus.layout
}
}
})
</script>

View File

@ -0,0 +1,31 @@
<template>
<footer class="bg-cloud-surface dark:bg-sky-black text-center border-t dark:border-t-sky-darkest">
<div class="d-container mx-auto py-8 px-4 sm:px-6 md:flex md:items-center md:justify-between lg:px-8">
<div class="flex justify-center space-x-3 md:order-2">
<a href="https://twitter.com/nuxt_js" target="_blank" rel="noopener" class="footer-link">
<span class="sr-only">Twitter</span>
<svg class="h-6 w-6" fill="currentColor" viewBox="0 0 24 24" aria-hidden="true">
<path d="M8.29 20.251c7.547 0 11.675-6.253 11.675-11.675 0-.178 0-.355-.012-.53A8.348 8.348 0 0022 5.92a8.19 8.19 0 01-2.357.646 4.118 4.118 0 001.804-2.27 8.224 8.224 0 01-2.605.996 4.107 4.107 0 00-6.993 3.743 11.65 11.65 0 01-8.457-4.287 4.106 4.106 0 001.27 5.477A4.072 4.072 0 012.8 9.713v.052a4.105 4.105 0 003.292 4.022 4.095 4.095 0 01-1.853.07 4.108 4.108 0 003.834 2.85A8.233 8.233 0 012 18.407a11.616 11.616 0 006.29 1.84" />
</svg>
</a>
<a href="https://github.com/nuxt/framework" target="_blank" rel="noopener" class="footer-link">
<span class="sr-only">GitHub</span>
<svg class="h-6 w-6" fill="currentColor" viewBox="0 0 24 24" aria-hidden="true">
<path fill-rule="evenodd" d="M12 2C6.477 2 2 6.484 2 12.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0112 6.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.202 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.943.359.309.678.92.678 1.855 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.019 10.019 0 0022 12.017C22 6.484 17.522 2 12 2z" clip-rule="evenodd" />
</svg>
</a>
</div>
<div class="mt-3 md:mt-0 md:order-1">
<p class="text-center text-base">
<a href="https://nuxtjs.org" class=" font-medium hover:underline">Nuxt 2 documentation</a>
</p>
</div>
</div>
</footer>
</template>
<style scoped lang="postcss">
.footer-link {
@apply text-cloud hover:text-cloud-dark dark:hover:text-cloud-light;
}
</style>

View File

@ -0,0 +1,62 @@
<template>
<header class="d-header">
<div class="flex items-center h-full px-1 mx-auto max-w-7xl sm:px-3 lg:px-6">
<NavigationButton
aria-label="mobileMenu"
class="w-12 h-12 lg:hidden text-gray-300 hover:text-cloud-lighter"
/>
<div class="flex items-center flex-1 justify-center lg:justify-start">
<Link :to="localePath('/')" aria-label="homeLink">
<!-- "mr-4 lg:mr-0" to optically center logo text -->
<Logo :settings="settings" class="h-8 mr-4 md:h-9 lg:mr-0" />
</Link>
</div>
<nav class="items-center hidden h-full lg:flex gap-4">
<NuxtLink v-for="(link, index) in links" :key="index" :to="link.to" class="font-medium px-2 py-1" :class="{ 'text-primary' : isActive(link) }">
{{ link.title }}
</NuxtLink>
</nav>
<div class="flex items-center justify-end gap-1 lg:flex-1">
<GitHubButton class="hidden lg:block" />
<TwitterButton class="hidden lg:block" />
<ColorSwitcher class="hidden lg:block" padding="p-3" />
<AlgoliaSearchBox v-if="settings && settings.algolia" :options="settings.algolia" :settings="settings" />
</div>
</div>
</header>
</template>
<script>
import { defineComponent, useContext, useRoute, computed } from '@nuxtjs/composition-api'
export default defineComponent({
props: {
links: {
type: Array,
default: () => []
}
},
setup () {
const { $docus } = useContext()
const route = useRoute()
const currentSlug = computed(() => {
return route.value.path !== '/' && route?.value?.params?.pathMatch
? route.value.params.pathMatch.split('/')[0]
: null
})
const settings = computed(() => $docus.settings.value)
function isActive (link) {
return `/${currentSlug.value}` === link.to
}
return {
settings,
isActive
}
}
})
</script>

View File

@ -0,0 +1,39 @@
<template>
<div class="relative w-full">
<AppHeader :links="headerLinks" />
<div class="lg:flex" :class="{ 'd-container': layout.aside }">
<slot v-if="['xs', 'sm', 'md'].includes($mq) || layout.aside" name="aside">
<AppAside :links="headerLinks" :class="layout.asideClass" />
</slot>
<div class="flex-auto w-full min-w-0 lg:static lg:max-h-full lg:overflow-visible">
<slot />
</div>
</div>
<AppFooter />
</div>
</template>
<script>
import { defineComponent } from '@nuxtjs/composition-api'
export default defineComponent({
data () {
return {
headerLinks: []
}
},
async fetch () {
const { $docus } = this
this.headerLinks = (await $docus
.search('/collections/header')
.fetch()).links
},
computed: {
layout () {
return this.$docus.layout.value
}
}
})
</script>

View File

@ -0,0 +1,71 @@
<template>
<nav ref="nav" class="flex flex-col gap-1 py-4 px-4 sm:px-6">
<NuxtLink v-for="(link, index) in links" :key="index" :to="link.to" class="font-medium my-1 py-1" :class="{ 'text-primary' : isActive(link) }">
{{ link.title }}
</NuxtLink>
</nav>
</template>
<script>
import { defineComponent, useContext, useRoute, ref, watch, computed } from '@nuxtjs/composition-api'
export default defineComponent({
props: {
links: {
type: Array,
default: () => []
}
},
setup (props) {
const { $menu } = useContext()
const route = useRoute()
const currentSlug = computed(() => {
return route.value.path !== '/' && route?.value?.params?.pathMatch
? route.value.params.pathMatch.split('/')[0]
: null
})
const nav = ref(null)
const openedLink = ref(null)
function selectActiveLink () {
if (currentSlug.value) {
for (const [index, link] of props.links.entries()) {
if (link.slug === currentSlug.value || link.items?.some(item => item.slug === currentSlug.value)) {
openedLink.value = index
break
}
}
} else {
openedLink.value = null
}
}
selectActiveLink()
watch($menu.visible, (value) => {
if (value) {
selectActiveLink()
}
})
function toggle (index) {
if (openedLink.value === index) {
openedLink.value = null
} else {
openedLink.value = index
}
}
function isActive (link) {
return `/${currentSlug.value}` === link.to
}
return {
openedLink,
toggle,
nav,
isActive
}
}
})
</script>

View File

@ -0,0 +1,100 @@
<template>
<nav
class="
flex flex-col
justify-start
max-w-sm
overflow-y-auto
text-sm
font-medium
lg:h-[reset]
h-(full-header)
d-scrollbar
py-4
px-4
sm:px-6
lg:pr-0 lg:pt-8
"
>
<!-- Title -->
<h5 v-if="['xs', 'sm', 'md'].includes($mq) && title" class="m-0 py-2 font-medium text-base uppercase">
{{ title }}
</h5>
<!-- Links list -->
<ul>
<template v-for="link in links">
<AsideNavigationItem
v-if="link.nested !== false && link.children.length"
:key="link.to"
:title="link.title"
:docs="link.children"
:collapse.sync="link.collapse"
/>
<AsideNavigationItem v-else :key="link.to" :docs="[link]" />
</template>
</ul>
<AsideBottom />
</nav>
</template>
<script lang="ts">
import { computed, defineComponent, ref, watch, useContext } from '@nuxtjs/composition-api'
export default defineComponent({
setup () {
const { $docus } = useContext()
// Replicate currentNav locally
const links = ref($docus.currentNav.value.links)
// Category title
const title = ref($docus.currentNav.value.title)
// Category slug
const slug = ref($docus.currentNav.value.slug)
// Check if current current navigation has directories
const isDirectory = computed(
() => links.value.filter(link => link.children && link.children.length > 0).length === 0
)
// Watch updates on currentNav
watch(
$docus.currentNav,
(newVal) => {
links.value = newVal.links
title.value = newVal.title
slug.value = newVal.slug
},
{ deep: true }
)
// Uncollapse current category on first navigation
watch(
links,
(newVal) => {
newVal.forEach((link) => {
if (link.children && link.children.length > 0) {
const isCategoryActive = link.children.some(document => $docus.isLinkActive(document.to))
if (isCategoryActive) {
link.collapse = false
}
}
})
},
{ immediate: true }
)
// Get parent
const parent = computed(() => $docus.currentNav.value.parent)
// Get last release value
const lastRelease = computed(() => $docus.lastRelease?.value)
return { isDirectory, links, title, slug, parent, lastRelease }
}
})
</script>

View File

@ -0,0 +1,121 @@
<template>
<div class="p-4 mt-4 mb-4 rounded-lg alert text-sm leading-relaxed" :class="[type]">
<div class="flex items-start">
<InjectComponent
v-if="icon"
:component="icon"
class="inline-flex mr-2 w-5 h-5 justify-center items-center text-1.2rem"
>
{{ icon }}
</InjectComponent>
<div class="flex-grow alert-content">
<Markdown unwrap="p">
<template #between>
<br>
</template>
</Markdown>
</div>
</div>
</div>
</template>
<script>
import { defineComponent } from '@nuxtjs/composition-api'
export default defineComponent({
props: {
icon: {
type: String,
default: ''
},
type: {
type: String,
default: 'info',
validator (value) {
return ['info', 'success', 'warning', 'danger'].includes(value)
}
}
}
})
</script>
<style lang="postcss" scoped>
.alert {
&.success {
@apply bg-green-50 dark:bg-green-800 dark:bg-opacity-25 text-green-600 dark:text-green-200;
>>> {
code {
@apply bg-green-100 dark:bg-green-900 dark:bg-opacity-50 shadow-none text-current;
}
a:hover {
code {
@apply border-green-400 dark:border-green-700;
}
}
}
}
&.info {
@apply bg-blue-50 dark:bg-blue-800 dark:bg-opacity-25 text-blue-600 dark:text-blue-200;
>>> {
code {
@apply bg-blue-100 dark:bg-blue-900 dark:bg-opacity-50 shadow-none text-current;
}
a:hover {
code {
@apply border-blue-400 dark:border-blue-700;
}
}
}
}
&.warning {
@apply bg-yellow-50 dark:bg-yellow-800 dark:bg-opacity-25 text-yellow-600 dark:text-yellow-100;
>>> {
code {
@apply bg-yellow-100 dark:bg-yellow-900 dark:bg-opacity-50 shadow-none text-current;
}
a:hover {
code {
@apply border-yellow-400 dark:border-yellow-700;
}
}
}
}
&.danger {
@apply bg-red-50 dark:bg-red-800 dark:bg-opacity-25 text-red-600 dark:text-red-100;
>>> {
code {
@apply bg-red-100 dark:bg-red-900 dark:bg-opacity-50 shadow-none text-current;
}
a:hover {
code {
@apply border-red-400 dark:border-red-700;
}
}
}
}
>>> {
strong {
@apply font-semibold text-current;
}
a {
@apply underline border-none font-semibold text-current;
code {
@apply border border-transparent border-dashed;
}
}
}
}
.alert >>> p {
@apply m-0 !important;
}
.dark .alert {
>>> {
a {
@apply text-current;
}
}
}
</style>

View File

@ -0,0 +1,46 @@
<template>
<Link class="button-link" :class="[size, bold ? 'font-semibold' : 'font-medium']" :to="href" :blank="blank">
<Markdown unwrap="p ul li" />
<template #href>
<IconExternalLink v-if="blank" class="w-4 h-4 ml-2" />
</template>
</Link>
</template>
<script>
import { defineComponent } from '@nuxtjs/composition-api'
export default defineComponent({
props: {
href: {
type: String,
default: ''
},
blank: {
type: Boolean,
default: false
},
size: {
type: String,
default: ''
},
bold: {
type: Boolean,
default: false
}
}
})
</script>
<style lang="postcss" scoped>
a.button-link {
@apply inline-flex items-center flex-none rounded-md mb-2 sm:mb-0 px-3 py-1.5 text-xs leading-4 text-black transition-colors duration-200 border border-transparent bg-primary-500 hover:bg-primary-400 focus:ring-2 focus:ring-offset-2 focus:ring-offset-white dark:focus:ring-offset-gray-900 focus:ring-primary-600 focus:outline-none;
&.medium {
@apply px-4 py-2.5 text-sm leading-4;
}
&.large {
@apply px-6 py-2.5 text-lg leading-6;
}
}
</style>

View File

@ -0,0 +1,121 @@
<template>
<canvas class="webgl" />
</template>
.webgl {
outline: none;
}
</style>
<script>
import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js'
export default {
mounted () {
// Canvas
const canvas = document.querySelector('canvas.webgl')
// Scene
const scene = new THREE.Scene()
// Models
let gem
let light
const gltfLoader = new GLTFLoader()
gltfLoader.load(
'/3D/gem.gltf',
(gltf) => {
console.log(gltf)
// Gem
gem = gltf.scene.children[6]
console.log(gltf.scene.children[6])
// Material setup
const textureLoader = new THREE.TextureLoader()
const roughnessTexture = textureLoader.load('/3D/roughness.jpeg')
gem.material.roughnessMap = roughnessTexture
gem.material.displacementScale = 0.15
gem.material.emissiveIntensity = 1
gem.material.refractionRatio = 1
gem.rotation.z = 0.5
scene.add(gem)
light = gltf.scene.children[0]
scene.add(light)
}
)
// Lights
const ambientLight = new THREE.AmbientLight(0xFFFFFF, 2)
scene.add(ambientLight)
const directionalLight = new THREE.DirectionalLight(0xFFFFFF, 3)
directionalLight.position.set(1, 1, 1)
scene.add(directionalLight)
// Settings
const sizes = {
width: 200,
height: 200
}
// Base camera
const camera = new THREE.PerspectiveCamera(
75,
sizes.width / sizes.height,
0.1,
100
)
camera.position.set(2, 2, 6)
scene.add(camera)
// Controls
const controls = new OrbitControls(camera, canvas)
controls.enableZoom = false
controls.target.set(0, 0.75, 0)
controls.enableDamping = true
// Lock Y Axis
controls.minPolarAngle = Math.PI / 2
controls.maxPolarAngle = Math.PI / 2
// Render
const renderer = new THREE.WebGLRenderer({
antialiasing: true,
canvas,
alpha: true
})
renderer.setClearColor(0x000000, 0)
renderer.shadowMap.enabled = true
renderer.shadowMap.type = THREE.PCFSoftShadowMap
renderer.setSize(sizes.width, sizes.height)
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2))
// Animations
const clock = new THREE.Clock()
let previousTime = 0
const tick = () => {
const elapsedTime = clock.getElapsedTime()
const deltaTime = elapsedTime - previousTime
previousTime = elapsedTime
if (gem) {
gem.rotation.y = 0.5 * elapsedTime
}
// Update controls
controls.update()
// Render
renderer.render(scene, camera)
// Call tick again on the next frame
window.requestAnimationFrame(tick)
}
tick()
}
}
</script>

View File

@ -0,0 +1,5 @@
<template>
<Link to="https://github.com/nuxt/nuxt.js" aria-label="gitHubLink" blank class="d-icon p-3">
<IconGitHub class="w-6 h-6" />
</Link>
</template>

View File

@ -0,0 +1,5 @@
<template>
<h1 class="font-normal font-serif text-display-5 xs:text-display-4 md:text-display-3 2xl:text-display-2 my-4">
<slot />
</h1>
</template>

View File

@ -0,0 +1,26 @@
<template>
<div class="inline-flex items-center space-x-3">
<svg viewBox="0 0 221 65" fill="none" xmlns="http://www.w3.org/2000/svg" class="h-8" @click="home">
<g clip-path="url(#a)">
<path fill="currentColor" d="M82.5623 18.5705h7.3017l15.474 24.7415V18.5705h6.741v35.0576h-7.252L89.3025 28.938v24.6901h-6.7402V18.5705ZM142.207 53.628h-6.282v-3.916c-1.429 2.7559-4.339 4.3076-8.015 4.3076-5.822 0-9.603-4.1069-9.603-10.0175V28.3847h6.282v14.3251c0 3.4558 2.146 5.8592 5.362 5.8592 3.524 0 5.974-2.7044 5.974-6.4099V28.3847h6.282V53.628ZM164.064 53.2289l-6.026-8.4144-6.027 8.4144h-6.69l9.296-13.1723-8.58-12.0709h6.843l5.158 7.2641 5.106-7.2641h6.895l-8.632 12.0709 9.295 13.1723h-6.638ZM183.469 20.7726v7.6116h7.149v5.1593h-7.149v12.5311c0 .4208.17.8245.473 1.1223.303.2978.715.4654 1.144.4661h5.532v5.9547h-4.137c-5.617 0-9.293-3.2062-9.293-8.8109V33.5484h-5.056v-5.1642h3.172c1.479 0 2.34-.8639 2.34-2.2932v-5.3184h5.825Z" />
<path fill-rule="evenodd" clip-rule="evenodd" d="M30.1185 11.5456c-1.8853-3.24168-6.5987-3.24169-8.484 0L1.08737 46.8747c-1.885324 3.2417.47133 7.2938 4.24199 7.2938H21.3695c-1.6112-1.4081-2.2079-3.8441-.9886-5.9341l15.5615-26.675-5.8239-10.0138Z" fill="#80EEC0" />
<path d="M43.1374 19.2952c1.5603-2.6523 5.461-2.6523 7.0212 0l17.0045 28.9057c1.5603 2.6522-.39 5.9676-3.5106 5.9676h-34.009c-3.1206 0-5.0709-3.3154-3.5106-5.9676l17.0045-28.9057ZM209.174 53.8005H198.483c0-1.8514.067-3.4526 0-6.0213h10.641c1.868 0 3.353.1001 4.354-.934 1-1.0341 1.501-2.3351 1.501-3.9029 0-1.8347-.667-3.2191-2.002-4.1532-1.301-.9674-2.985-1.4511-5.054-1.4511h-2.601v-5.2539h2.652c1.701 0 3.119-.4003 4.253-1.2009 1.134-.8006 1.701-1.9849 1.701-3.5527 0-1.301-.434-2.3351-1.301-3.1023-.834-.8007-2.001-1.201-3.503-1.201-1.634 0-2.918.4837-3.853 1.4511-.9.9674-1.401 2.1517-1.501 3.5527h-6.254c.133-3.2358 1.251-5.7877 3.352-7.6558 2.135-1.868 4.887-2.8021 8.256-2.8021 2.402 0 4.42.4337 6.055 1.301 1.668.834 2.919 1.9515 3.753 3.3525.867 1.4011 1.301 2.9523 1.301 4.6536 0 1.9681-.551 3.636-1.651 5.0037-1.068 1.3344-2.402 2.235-4.004 2.7021 1.969.4003 3.57 1.3677 4.804 2.9022 1.234 1.5011 1.852 3.4025 1.852 5.7043 0 1.9347-.468 3.7028-1.402 5.304-.934 1.6012-2.301 2.8855-4.103 3.8529-1.768.9674-3.953 1.4511-6.555 1.4511Z" fill="#00DC82" />
</g>
<defs><clipPath id="a"><path fill="#fff" d="M0 0h221v65H0z" /></clipPath></defs>
</svg>
<span class="inline-flex items-center mt-1.2 px-2 py-0.5 rounded text-xs font-medium font-mono bg-cloud-surface dark:bg-sky-dark dark:text-white">beta</span>
</div>
</template>
<script>
export default {
methods: {
home () {
if (this.$route.path === '/') {
// scroll to top
window.scrollTo(0, 0)
}
}
}
}
</script>

View File

@ -0,0 +1,18 @@
<template>
<Component :is="tag" class="relative w-full d-container-content">
<slot />
</Component>
</template>
<script>
import { defineComponent } from '@nuxtjs/composition-api'
export default defineComponent({
props: {
tag: {
type: String,
default: 'div'
}
}
})
</script>

View File

@ -0,0 +1,84 @@
<template>
<!-- eslint-disable-next-line vue/require-component-is -->
<component
v-bind="linkProps"
:aria-label="ariaLabel"
class="font-medium rounded-md"
:class="[
iconLeft || iconRight ? 'inline-flex items-center px-4 py-2.5' : 'px-4 py-2.5',
{ 'text-md 2xl:text-base ': size === 'lg' },
{ 'text-sm 2xl:text-md ': size === 'md' },
{ 'text-xs 2xl:text-sm ': size === 'sm' }
]"
>
<div v-if="iconLeft" class="h-full flex items-center justify-center">
<Component :is="iconLeft" class="mr-2" :class="{ 'w-5 h-5': size === 'lg' }" />
</div>
<slot />
<div v-if="iconRight" class="h-full flex items-center justify-center">
<Component :is="iconRight" class="ml-2" :class="{ 'w-5 h-5': size === 'lg' }" />
</div>
</component>
</template>
<script>
import { defineComponent, computed } from '@nuxtjs/composition-api'
export default defineComponent({
props: {
to: {
type: String,
default: ''
},
href: {
type: String,
default: ''
},
size: {
type: String,
default: 'lg',
validator (value) {
return ['sm', 'md', 'lg'].includes(value)
}
},
iconLeft: {
type: String,
default: null
},
iconRight: {
type: String,
default: null
},
ariaLabel: {
type: String,
default: null
}
},
setup (props) {
const linkProps = computed(() => {
const { to, href } = props
if (to?.length) {
return {
is: 'Link',
to
}
} else if (href?.length) {
return {
is: 'Link',
static: true,
to: '',
href,
blank: true
}
} else {
return {
is: 'button'
}
}
})
return {
linkProps
}
}
})
</script>

View File

@ -0,0 +1,45 @@
<template>
<div ref="star" class="absolute bg-primary-300 dark:bg-white rounded-full opacity-100 star" :style="style" />
</template>
<script>
import { defineComponent, ref, computed, onMounted } from '@nuxtjs/composition-api'
export default defineComponent({
setup () {
const style = ref({})
const randomY = ref(null)
const randomX = ref(null)
const randomRadius = computed(() => Math.round(Math.random() * Math.round(4)))
const randomDuration = computed(() => Math.round(Math.random() * Math.round(10)))
onMounted(() => {
randomX.value = Math.random() * Math.floor(document.documentElement.clientWidth)
randomY.value = Math.random() * Math.floor(document.documentElement.clientHeight)
style.value = {
top: randomY.value + 'px',
left: randomX.value + 'px',
height: randomRadius.value + 'px',
width: randomRadius.value + 'px',
animationDuration: randomDuration.value + 's'
}
})
return {
style,
randomRadius,
randomDuration,
randomY,
randomX
}
}
})
</script>
<style lang="postcss" scoped>
/* Stars */
.star {
animation-name: fade;
animation-timing-function: linear;
animation-iteration-count: infinite;
animation-direction: alternate;
}
</style>

View File

@ -0,0 +1,5 @@
<template>
<Link to="https://twitter.com/nuxt_js" aria-label="twitterLink" blank class="d-icon p-3">
<IconTwitter class="w-6 h-6" />
</Link>
</template>

View File

@ -0,0 +1,3 @@
<template>
<svg width="28" height="25" viewBox="0 0 28 25" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M11.9467 22.3333C10 25.0933 6.20001 25.7867 3.45334 23.8667C0.720008 21.9467 0.0800078 18.12 2.00001 15.3333C2.53695 14.5538 3.24758 13.9096 4.0759 13.4514C4.90423 12.9933 5.82763 12.7338 6.77334 12.6933L6.84001 14.6C5.62667 14.6933 4.45334 15.32 3.69334 16.4133C2.36001 18.3333 2.77334 20.92 4.60001 22.2133C6.44001 23.4933 9.01334 23 10.3467 21.0933C10.76 20.4933 11 19.84 11.0933 19.1733V17.8267L18.5333 17.7733L18.6267 17.6267C19.3333 16.4 20.8667 15.9733 22.0667 16.6667C22.3539 16.8347 22.6052 17.0577 22.8062 17.3229C23.0072 17.5881 23.154 17.8903 23.2381 18.2122C23.3223 18.5341 23.3423 18.8695 23.2969 19.1991C23.2514 19.5287 23.1415 19.8462 22.9733 20.1333C22.2667 21.3467 20.72 21.7733 19.52 21.08C18.9733 20.7733 18.5867 20.28 18.4133 19.72L12.9867 19.7467C12.8277 20.673 12.4732 21.5548 11.9467 22.3333V22.3333ZM21.6533 12.8133C25.0267 13.2267 27.4267 16.2533 27.0133 19.5733C26.6 22.9067 23.5333 25.2667 20.16 24.8533C19.2232 24.7442 18.3239 24.4219 17.5312 23.9111C16.7384 23.4003 16.0732 22.7146 15.5867 21.9067L17.24 20.9467C17.582 21.4763 18.0365 21.9241 18.5711 22.2582C19.1058 22.5923 19.7074 22.8046 20.3333 22.88C22.6667 23.16 24.7333 21.5733 25.0133 19.3467C25.2933 17.12 23.64 15.08 21.3333 14.8C20.6133 14.72 19.92 14.8133 19.2933 15.04L18.16 15.6267L14.72 9.26667H14.4267C13.7554 9.24713 13.1192 8.96269 12.657 8.47552C12.1948 7.98834 11.9442 7.33803 11.96 6.66667C12 5.28001 13.2 4.20001 14.6 4.25334C16 4.33334 17.1067 5.46667 17.0667 6.85334C17.04 7.44001 16.8133 7.97334 16.4533 8.38667L18.9867 13.0667C19.8133 12.8 20.72 12.7067 21.6533 12.8133V12.8133ZM9.00001 9.18667C7.66667 6.05334 9.08001 2.46667 12.16 1.16001C15.2533 -0.14666 18.8267 1.33334 20.16 4.46667C20.9467 6.29334 20.7867 8.29334 19.8933 9.89334L18.24 8.93334C18.8 7.85334 18.8933 6.53334 18.36 5.29334C17.4533 3.16001 15.04 2.13334 12.9733 3.00001C10.8933 3.88001 9.96001 6.33334 10.8667 8.46667C11.24 9.34667 11.8667 10.0267 12.6267 10.48L13.1467 10.76L9.05334 17.4133C9.09334 17.48 9.14668 17.56 9.18668 17.6667C9.84001 18.88 9.38667 20.4133 8.16001 21.0667C6.94667 21.72 5.41334 21.24 4.74667 19.9867C4.09334 18.7467 4.54667 17.2133 5.77334 16.56C6.29334 16.28 6.86667 16.2133 7.41334 16.3333L10.4933 11.3067C9.86667 10.7333 9.33334 10.0133 9.00001 9.18667V9.18667Z" fill="currentColor" /></svg>
</template>

View File

@ -0,0 +1,13 @@
<template>
<svg
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
aria-hidden="true"
role="img"
class="iconify iconify--bx"
width="32"
height="32"
preserveAspectRatio="xMidYMid meet"
viewBox="0 0 24 24"
><path d="M20 4H4a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V6a2 2 0 0 0-2-2zM6.414 15.707L5 14.293L7.293 12L5 9.707l1.414-1.414L10.121 12l-3.707 3.707zM19 16h-7v-2h7v2z" fill="currentColor" /></svg>
</template>

View File

@ -0,0 +1,5 @@
<template>
<svg xmlns="http://www.w3.org/2000/svg" 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>
</template>

View File

@ -0,0 +1,3 @@
<template>
<svg width="1em" height="1em" viewBox="0 0 24 24"><path d="M14.6 16.6l4.6-4.6l-4.6-4.6L16 6l6 6l-6 6l-1.4-1.4m-5.2 0L4.8 12l4.6-4.6L8 6l-6 6l6 6l1.4-1.4z" fill="currentColor" /></svg>
</template>

View File

@ -0,0 +1,13 @@
<template>
<svg
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
aria-hidden="true"
role="img"
class="iconify iconify--bx"
width="32"
height="32"
preserveAspectRatio="xMidYMid meet"
viewBox="0 0 24 24"
><path d="M20 3H4c-1.103 0-2 .897-2 2v14c0 1.103.897 2 2 2h16c1.103 0 2-.897 2-2V5c0-1.103-.897-2-2-2zM4 19V7h16l.002 12H4z" fill="currentColor" /><path d="M9.293 9.293L5.586 13l3.707 3.707l1.414-1.414L8.414 13l2.293-2.293zm5.414 0l-1.414 1.414L15.586 13l-2.293 2.293l1.414 1.414L18.414 13z" fill="currentColor" /></svg>
</template>

View File

@ -0,0 +1,4 @@
<template>
<svg width="1em" height="1em" viewBox="0 0 36 36"><path class="clr-i-outline clr-i-outline-path-1" d="M30 9H16.42l-2.31-3.18A2 2 0 0 0 12.49 5H6a2 2 0 0 0-2 2v22a2 2 0 0 0 2 2h24a2 2 0 0 0 2-2V11a2 2 0 0 0-2-2zm0 20H6V13h7.31a2 2 0 0 0 2-2H6V7h6.49l2.61 3.59a1 1 0 0 0 .81.41H30z" fill="currentColor" /></svg>
</template>

View File

@ -0,0 +1,13 @@
<template>
<svg
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
aria-hidden="true"
role="img"
class="iconify iconify--entypo"
width="32"
height="32"
preserveAspectRatio="xMidYMid meet"
viewBox="0 0 20 20"
><path d="M4.254 19.567c.307-.982.77-2.364 1.391-4.362c2.707-.429 3.827.341 5.546-2.729c-1.395.427-3.077-.792-2.987-1.321c.091-.528 3.913.381 6.416-3.173c-3.155.696-4.164-.836-3.757-1.067c.939-.534 3.726-.222 5.212-1.669c.766-.745 1.125-2.556.813-3.202c-.374-.781-2.656-1.946-3.914-1.836c-1.258.109-3.231 4.79-3.817 4.754c-.584-.037-.703-2.098.319-4.013c-1.077.477-3.051 1.959-3.67 3.226c-1.153 2.357.108 7.766-.296 7.958c-.405.193-1.766-2.481-2.172-3.694c-.555 1.859-.568 3.721 1.053 6.194c-.611 1.623-.945 3.491-.996 4.441c-.024.759.724.922.859.493z" fill="currentColor" /></svg>
</template>

View File

@ -0,0 +1,4 @@
<template>
<svg width="1em" height="1em" viewBox="0 0 36 36"><path class="clr-i-outline clr-i-outline-path-1" d="M21.89 4H7.83A1.88 1.88 0 0 0 6 5.91v24.18A1.88 1.88 0 0 0 7.83 32h20.34A1.88 1.88 0 0 0 30 30.09V11.92zm-.3 2.49l6 5.9h-6zM8 30V6h12v8h8v16z" fill="currentColor" /></svg>
</template>

View File

@ -0,0 +1,4 @@
<template>
<svg width="1em" height="1em" viewBox="0 0 36 36"><path d="M33.83 23.43a1.16 1.16 0 0 0-.71-1.12l-1.68-.5c-.09-.24-.18-.48-.29-.71l.78-1.44a1.16 1.16 0 0 0-.21-1.37l-1.42-1.41a1.16 1.16 0 0 0-1.37-.2l-1.45.76a7.84 7.84 0 0 0-.76-.32l-.48-1.58a1.15 1.15 0 0 0-1.11-.77h-2a1.16 1.16 0 0 0-1.11.82l-.47 1.54a7.76 7.76 0 0 0-.77.32l-1.42-.76a1.16 1.16 0 0 0-1.36.2l-1.45 1.4a1.16 1.16 0 0 0-.21 1.38l.74 1.33a7.64 7.64 0 0 0-.31.74l-1.58.47a1.15 1.15 0 0 0-.83 1.11v2a1.15 1.15 0 0 0 .83 1.1l1.59.47a7.53 7.53 0 0 0 .31.72l-.78 1.46a1.16 1.16 0 0 0 .21 1.37l1.42 1.4a1.16 1.16 0 0 0 1.37.21l1.48-.78c.23.11.47.2.72.29l.49 1.62a1.16 1.16 0 0 0 1.11.81h2a1.16 1.16 0 0 0 1.11-.82l.47-1.58c.24-.08.47-.18.7-.29l1.5.79a1.16 1.16 0 0 0 1.36-.2l1.42-1.4a1.16 1.16 0 0 0 .21-1.38l-.79-1.45q.16-.34.29-.69L33 26.5a1.15 1.15 0 0 0 .83-1.11zm-1.6 1.63l-2.11.62l-.12.42a6 6 0 0 1-.5 1.19l-.21.38l1 1.91l-1 1l-2-1l-.37.2a6.21 6.21 0 0 1-1.2.49l-.42.12l-.63 2.09h-1.25l-.63-2.08l-.42-.12a6.23 6.23 0 0 1-1.21-.49l-.37-.2l-1.94 1l-1-1l1-1.94l-.22-.38a6 6 0 0 1-.46-1.27l-.17-.37l-2-.63v-1.31l2-.61l.13-.41a5.94 5.94 0 0 1 .53-1.23l.24-.44l-1-1.85l1-.94l1.89 1l.38-.21a6.23 6.23 0 0 1 1.26-.52l.41-.12l.63-2h1.38l.62 2l.41.12a6.21 6.21 0 0 1 1.22.52l.38.21l1.92-1l1 1l-1 1.89l.21.38a6.08 6.08 0 0 1 .5 1.21l.12.42l2.06.61z" class="clr-i-outline clr-i-outline-path-1" fill="currentColor" /><path d="M24.12 20.35a4 4 0 1 0 4.08 4a4.06 4.06 0 0 0-4.08-4zm0 6.46a2.43 2.43 0 1 1 2.48-2.43a2.46 2.46 0 0 1-2.48 2.44z" class="clr-i-outline clr-i-outline-path-2" fill="currentColor" /><path d="M14.49 31H6V5h20v7.89a3.2 3.2 0 0 1 2 1.72V5a2 2 0 0 0-2-2H6a2 2 0 0 0-2 2v26a2 2 0 0 0 2 2h10.23l-1.1-1.08a3.11 3.11 0 0 1-.64-.92z" class="clr-i-outline clr-i-outline-path-3" fill="currentColor" /></svg>
</template>

View File

@ -0,0 +1,4 @@
<template>
<svg width="1em" height="1em" viewBox="0 0 24 24"><path d="M2.6 10.59L8.38 4.8l1.69 1.7c-.24.85.15 1.78.93 2.23v5.54c-.6.34-1 .99-1 1.73a2 2 0 0 0 2 2a2 2 0 0 0 2-2c0-.74-.4-1.39-1-1.73V9.41l2.07 2.09c-.07.15-.07.32-.07.5a2 2 0 0 0 2 2a2 2 0 0 0 2-2a2 2 0 0 0-2-2c-.18 0-.35 0-.5.07L13.93 7.5a1.98 1.98 0 0 0-1.15-2.34c-.43-.16-.88-.2-1.28-.09L9.8 3.38l.79-.78c.78-.79 2.04-.79 2.82 0l7.99 7.99c.79.78.79 2.04 0 2.82l-7.99 7.99c-.78.79-2.04.79-2.82 0L2.6 13.41c-.79-.78-.79-2.04 0-2.82z" fill="currentColor" /></svg>
</template>

View File

@ -0,0 +1,10 @@
<template>
<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M7.02751 0.333496C3.34571 0.333496 0.333332 3.40836 0.333332 7.16653C0.333332 10.1845 2.23002 12.7468 4.90769 13.6579C5.2424 13.7149 5.35397 13.4871 5.35397 13.3163C5.35397 13.1454 5.35397 12.7468 5.35397 12.1774C3.51307 12.576 3.12257 11.2664 3.12257 11.2664C2.84365 10.4692 2.39737 10.2414 2.39737 10.2414C1.72795 9.8428 2.39737 9.8428 2.39737 9.8428C3.06679 9.89974 3.4015 10.5261 3.4015 10.5261C4.01513 11.5511 4.96347 11.2664 5.35397 11.0955C5.40975 10.64 5.57711 10.3553 5.80024 10.1845C4.29405 10.0136 2.73208 9.44421 2.73208 6.82488C2.73208 6.08463 3.011 5.45827 3.4015 5.00274C3.4015 4.77497 3.12257 4.09166 3.51307 3.18059C3.51307 3.18059 4.07091 3.00977 5.35397 3.8639C5.91181 3.69307 6.46966 3.63613 7.02751 3.63613C7.58536 3.63613 8.14321 3.69307 8.70105 3.8639C9.98411 2.95283 10.542 3.18059 10.542 3.18059C10.9324 4.14861 10.6535 4.83191 10.5977 5.00274C11.044 5.45827 11.2672 6.08463 11.2672 6.82488C11.2672 9.44421 9.70518 10.0136 8.19899 10.1845C8.42213 10.4122 8.64527 10.8108 8.64527 11.4372C8.64527 12.3482 8.64527 13.0885 8.64527 13.3163C8.64527 13.4871 8.75684 13.7149 9.09155 13.6579C11.7692 12.7468 13.6659 10.1845 13.6659 7.16653C13.7217 3.40836 10.7093 0.333496 7.02751 0.333496Z"
fill="currentColor"
/>
</svg>
</template>

View File

@ -0,0 +1,13 @@
<template>
<svg
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
aria-hidden="true"
role="img"
class="iconify iconify--carbon"
width="32"
height="32"
preserveAspectRatio="xMidYMid meet"
viewBox="0 0 32 32"
><path d="M17 24.184V20h-2v4.184a3 3 0 1 0 2 0z" fill="currentColor" /><path d="M26 12a3.996 3.996 0 0 0-3.858 3H9.858a4 4 0 1 0 0 2h12.284A3.993 3.993 0 1 0 26 12zM6 18a2 2 0 1 1 2-2a2.002 2.002 0 0 1-2 2zm20 0a2 2 0 1 1 2-2a2.002 2.002 0 0 1-2 2z" fill="currentColor" /><path d="M19 5a3 3 0 1 0-4 2.816V12h2V7.816A2.992 2.992 0 0 0 19 5z" fill="currentColor" /></svg>
</template>

View File

@ -0,0 +1,12 @@
<template>
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0)">
<path d="M3 1.99999L2 2.99999L4.2 6.08099C4.29262 6.21074 4.41491 6.31646 4.55668 6.38934C4.69845 6.46223 4.85559 6.50017 5.015 6.49999H5.085C5.21648 6.49989 5.34669 6.52571 5.46818 6.57599C5.58966 6.62627 5.70004 6.70001 5.793 6.79299L8.468 9.46799L5.851 12.122C5.40339 11.9902 4.93124 11.9646 4.472 12.0471C4.01275 12.1296 3.57905 12.318 3.2053 12.5973C2.83154 12.8766 2.52802 13.2392 2.3188 13.6563C2.10959 14.0733 2.00043 14.5334 2 15C2.0006 15.4299 2.0936 15.8547 2.27271 16.2456C2.45182 16.6364 2.71285 16.9842 3.03811 17.2654C3.36337 17.5466 3.74526 17.7545 4.15792 17.8752C4.57057 17.9959 5.00434 18.0265 5.42985 17.9649C5.85535 17.9033 6.26264 17.7509 6.62413 17.5182C6.98561 17.2854 7.29284 16.9777 7.52501 16.6158C7.75717 16.2539 7.90884 15.8464 7.96975 15.4208C8.03065 14.9952 7.99936 14.5614 7.878 14.149L10.532 11.532L11.5 12.5L11.195 13.414C11.1364 13.5902 11.128 13.7792 11.1707 13.9599C11.2135 14.1405 11.3057 14.3057 11.437 14.437L14.793 17.793C14.9805 17.9805 15.2348 18.0858 15.5 18.0858C15.7652 18.0858 16.0195 17.9805 16.207 17.793L17.793 16.207C17.9805 16.0195 18.0858 15.7652 18.0858 15.5C18.0858 15.2348 17.9805 14.9805 17.793 14.793L14.437 11.437C14.3058 11.3057 14.1405 11.2135 13.9599 11.1707C13.7792 11.128 13.5902 11.1364 13.414 11.195L12.5 11.5L11.54 10.54L14.22 7.89699C14.6646 8.01567 15.1305 8.03066 15.5818 7.9408C16.0331 7.85095 16.4577 7.65866 16.8229 7.37874C17.1882 7.09883 17.4842 6.73878 17.6883 6.32636C17.8924 5.91393 17.999 5.46015 18 4.99999C18 4.73099 17.965 4.46999 17.898 4.22299L15.758 6.36399L14 5.99999L13.636 4.24299L15.777 2.10199C15.2677 1.96505 14.7313 1.9648 14.2219 2.10125C13.7124 2.2377 13.248 2.50604 12.8753 2.87922C12.5026 3.2524 12.2349 3.71723 12.0991 4.22685C11.9634 4.73647 11.9644 5.27287 12.102 5.78199L9.462 8.45999L6.793 5.79299C6.60545 5.6055 6.50006 5.35119 6.5 5.08599V5.01499C6.50002 4.85575 6.462 4.69881 6.38912 4.55723C6.31624 4.41564 6.21061 4.29351 6.081 4.20099L3 1.99999ZM12.646 12.646C12.6924 12.5994 12.7476 12.5625 12.8084 12.5373C12.8691 12.5121 12.9342 12.4991 13 12.4991C13.0658 12.4991 13.1309 12.5121 13.1916 12.5373C13.2524 12.5625 13.3076 12.5994 13.354 12.646L16.354 15.646C16.4005 15.6925 16.4374 15.7477 16.4625 15.8084C16.4877 15.8691 16.5006 15.9342 16.5006 16C16.5006 16.0657 16.4877 16.1308 16.4625 16.1916C16.4374 16.2523 16.4005 16.3075 16.354 16.354C16.3075 16.4005 16.2523 16.4374 16.1916 16.4625C16.1308 16.4877 16.0657 16.5006 16 16.5006C15.9343 16.5006 15.8692 16.4877 15.8084 16.4625C15.7477 16.4374 15.6925 16.4005 15.646 16.354L12.646 13.354C12.5994 13.3075 12.5625 13.2524 12.5373 13.1916C12.5121 13.1309 12.4991 13.0658 12.4991 13C12.4991 12.9342 12.5121 12.8691 12.5373 12.8084C12.5625 12.7476 12.5994 12.6924 12.646 12.646ZM5 13L5.471 13.242L6 13.268L6.287 13.713L6.732 14L6.758 14.529L7 15L6.758 15.471L6.732 16L6.287 16.287L6 16.732L5.471 16.758L5 17L4.529 16.758L4 16.732L3.713 16.287L3.268 16L3.242 15.471L3 15L3.242 14.529L3.268 14L3.713 13.713L4 13.268L4.529 13.242L5 13Z" fill="currentColor" />
</g>
<defs>
<clipPath id="clip0">
<rect width="16" height="16" fill="white" transform="translate(2 2)" />
</clipPath>
</defs>
</svg>
</template>

View File

@ -0,0 +1,3 @@
<template>
<svg width="1em" height="1em" viewBox="0 0 24 24"><path d="M4 10v4h2v-3h1v3h1v-4H4m5 0v5h2v-1h2v-4H9m3 1v2h-1v-2h1m2-1v4h2v-3h1v3h1v-3h1v3h1v-4h-6M3 9h18v6h-9v1H8v-1H3V9z" fill="currentColor" /></svg>
</template>

View File

@ -0,0 +1,3 @@
<template>
<svg viewBox="0 0 568 289" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M105.365 183.284C161.654 157.422 219.244 64.129 227.008 7.046M181.669 1.788C177.258 33.024 83.023 133.863.76 177.934M189.542 2.732c61.84 114.358 214.646 306.74 347.993 141.883M231.098 1.304c23.17 105.268 181.771 292.873 290.458 139.889M541.033 136.009c1.939 27.604 6.824 90.458 25.987 97.575M132.872 72.038v119.676M139.04 65.938v125.776M253.581 59.892V197.26M258.992 69.637l.842 128.066M289.779 114.709v90.618M295.385 121.554l-.003 84.341M319.711 147.263v61.886M325.301 152.285l.723 57.28M352.124 173.609v43.94M358.424 177.317l.003 40.897M382.042 189.402v29.78M387.559 191.789l.784 27.827M414.444 199.134v21.416M420.23 199.346l.001 21.897M439.916 198.501v22.05M445.701 197.202v24.041M463.16 192.107v29.031M468.945 189.609v32.448M486.444 178.489v43.352M492.229 174.023l-.002 48.856M504.637 161.891v63.006M510.445 155.54v71.24M548.386 196.564v35.017M554.195 216.899l-.005 16.564M165.132 33.843v157.876M171.291 24.5l-.002 167.223" stroke="#00DC82" stroke-width="2" /><path d="M189.156 1.338l4.584-.395v286.53l-4.584 1.516V1.338z" fill="#40E5A1" /><path fill="#00DC82" d="M184.938 26.536h38.323v8.822h-38.323zM182.97 59.135h38.323v8.822H182.97zM182.97 91.733h38.323v8.822H182.97zM184.938 124.333h38.323v8.822h-38.323z" /><path d="M227.479 1.336l4.585-.394V287.47l-4.585 1.516V1.337zM522.195 136.145l2.643-.206v127.914l-2.642 1.05-.001-128.758z" fill="#40E5A1" /><path fill="#00DC82" d="M520.303 140.366h17.191v4.186h-17.191zM519.42 155.834h17.191v4.186H519.42zM519.42 171.304h17.191v4.186H519.42zM520.303 186.772h17.191v4.186h-17.191z" /><path d="M539.386 136.142l2.643-.206V263.85l-2.643 1.056V136.142z" fill="#40E5A1" /><path d="M567.372 238.089C444.413 215.892.278 215.177.278 215.177v-38.119c110.66-3.113 458.828 38.476 567.094 55.602v5.429z" fill="#00DC82" /><path d="M518.911 136.595l.317-.032-.317.099v-.067zM536.102 136.592l.317-.032-.317.099v-.067z" stroke="#00E889" /><path fill="#00DC82" d="M180.719 1.338h8.438v287.651h-8.438zM219.042 1.338h8.438v287.651h-8.438zM518.411 136.146h3.785v128.758h-3.785zM535.602 136.146h3.785v128.758h-3.785z" /></svg>
</template>

View File

@ -0,0 +1,3 @@
<template>
<svg viewBox="0 0 450 325" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M293.063 10.056c56.455 7.127 145.001 79.138 140.169 192.691M293.063 16.666c52.999 6.827 136.412 77.692 131.798 181.466M291.992 23.152c49.096 6.552 126.443 69.359 124.458 172.627" stroke="#00DC82" stroke-width="2" /><circle cx="248.964" cy="180.002" r="143.734" stroke="#00DC82" stroke-width="2" /><circle cx="248.964" cy="177.258" r="37.599" stroke="#00DC82" stroke-width="3" /><path d="M273.682 117.498l-2.035 5.311c21.301 8.989 36.549 29.953 36.937 54.434h5.684c-.39-26.902-17.152-49.935-40.586-59.745z" fill="#00DC82" /><path d="M281.544 95.64l-2.825 7.577c29.555 12.213 50.873 40.764 51.412 74.023h7.885c-.541-36.549-23.957-68.272-56.472-81.6z" fill="#00DC82" /><path d="M291.548 67.793l-3.809 9.736c39.878 16.478 68.023 54.835 68.75 99.712h10.64c-.73-49.317-31.708-91.464-75.581-109.448z" fill="#00DC82" /><circle cx="248.964" cy="177.259" r="18.392" stroke="#00DC82" stroke-width="3" /><circle cx="142.228" cy="199.905" r="14.94" stroke="#00DC82" stroke-width="2" /><circle cx="225.106" cy="281.648" r="14.94" stroke="#00DC82" stroke-width="2" /><circle cx="181.709" cy="194.289" r="9.324" stroke="#00DC82" stroke-width="2" /><circle cx="189.858" cy="235.991" r="13.631" stroke="#00DC82" stroke-width="2" /><circle cx="248.279" cy="180.688" r="130.201" stroke="#00DC82" stroke-width="3" /><path d="M401.929 282.208c24.245 0 43.9-19.655 43.9-43.901 0-24.245-19.655-43.9-43.9-43.9-3.93 0-6.503.423-10.127 1.391l-.297-4.175c3.734-.931 6.402-1.331 10.424-1.331 26.518 0 48.016 21.497 48.016 48.015 0 26.519-21.498 48.016-48.016 48.016-16.015 0-30.199-7.84-38.922-19.892l2.62-3.43c7.902 11.594 21.213 19.207 36.302 19.207z" fill="#00DC82" /><path d="M401.929 272.605c19.767 0 35.669-15.73 35.669-34.983 0-19.254-15.902-34.983-35.669-34.983-4.343 0-7.588.52-11.433 1.911v-4.348c3.887-1.245 7.123-1.679 11.433-1.679 21.973 0 39.785 17.505 39.785 39.099 0 21.593-17.812 39.098-39.785 39.098-14.139 0-26.555-7.248-33.611-18.17l2.744-3.391c6.163 10.414 17.651 17.446 30.867 17.446z" fill="#00DC82" /><path d="M401.929 263.002c13.638 0 24.694-11.056 24.694-24.694s-11.056-24.694-24.694-24.694c-5.881 0-10.474 2.055-14.715 5.487l.674-5.487c4.336-2.613 8.609-4.116 14.041-4.116 15.911 0 28.809 12.899 28.809 28.81s-12.898 28.809-28.809 28.809c-13.051 0-23.827-6.597-27.369-18.497l3.264-4.116c1.959 11.679 11.869 18.498 24.105 18.498z" fill="#00DC82" /><path d="M108.631 149.881H75.365V69.547c0-37.555 30.444-68 68-68h138.164v38.65" stroke="#00DC82" stroke-width="3" /><path stroke="#00DC82" stroke-width="2" d="M283.49 7.708h8.811v17.943h-8.811zM48.44 102.206h25.925v28.717H48.44zM48.838 107.08H2.796M48.838 116.868H2.796M48.838 126.392H2.796M115.194 232.746H58.853l-17.877 18.449v52.009h133.781" /><path d="M41.282 298.48L9.887 283.065l3.611-8.802 27.784 13.013M40.976 272.848l-30.243-14.67 3.61-8.802 26.633 12.639M8.43 242.485l7.372 3.24-6.935 15.778-7.371-3.24zM8.631 268.316l6.142 2.473L8.648 286l-6.142-2.473zM253.637 297.644v-63.268c34.998-2.159 54.249-25.026 54.249-51.609h58.098c-14.301 95.667-83.405 116.731-112.347 114.877zM137.434 176.212h58.716c2.215-32.526 25.277-50.39 52.061-50.356v-58.35c-80.088 0-110.777 74.058-110.777 108.706zM148.271 176.579c3.346-36.424 34.406-98.159 100.169-98.159M162.333 176.597c2.876-31.305 29.57-84.362 86.09-84.362M178.238 176.617c2.344-25.514 24.101-68.757 70.165-68.757M264.06 233.927v63.561M276.397 230.031v65.127M288.063 222.684v68.544M300.951 208.125v78.11M314.2 182.767v95.294M314.482 196.151h48.525M314.267 210.912h45.076M313.969 226.273h39.435M314.484 241.378l31.981.055M314.481 255.77l21.778-.028M313.804 268.183h11.119M141.187 185.053l40.49-.061M190.008 190.066l46.787 82.304M131.048 209.839l81.679 80.139" stroke="#00DC82" stroke-width="2" /></svg>
</template>

View File

@ -0,0 +1,13 @@
<template>
<svg
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
aria-hidden="true"
role="img"
class="iconify iconify--fluent"
width="32"
height="32"
preserveAspectRatio="xMidYMid meet"
viewBox="0 0 28 28"
><g fill="none"><path d="M18.184 5.55l6.555 6.554a4.305 4.305 0 0 1-4.038 7.234v.246A2.415 2.415 0 0 1 18.286 22H15.5v-.826A3.173 3.173 0 0 0 12.335 18h-1.59a.75.75 0 0 0 0 1.5h1.59c.917 0 1.666.75 1.666 1.674V22H7.399A2.401 2.401 0 0 1 5 19.584v-3.15c0-.233.015-.463.043-.69A2.875 2.875 0 1 1 7.55 11.82c.831-.519 1.814-.82 2.868-.82h4.849c.729 0 1.424.144 2.06.404c.197-.332.438-.615.72-.905l-2.406-2.406a1.798 1.798 0 1 1 2.543-2.543z" fill="currentColor" /></g></svg>
</template>

View File

@ -0,0 +1,13 @@
<template>
<svg
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
aria-hidden="true"
role="img"
class="iconify iconify--carbon"
width="32"
height="32"
preserveAspectRatio="xMidYMid meet"
viewBox="0 0 32 32"
><path d="M8 16l8-8l8 8l-8 8z" fill="currentColor" /><path d="M16 4A12 12 0 1 1 4 16A12.014 12.014 0 0 1 16 4m0-2a14 14 0 1 0 14 14A14 14 0 0 0 16 2z" fill="currentColor" /></svg>
</template>

View File

@ -0,0 +1,10 @@
<template>
<svg fill="none" viewBox="0 0 24 24">
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M22 5.897c-.75.33-1.5.577-2.333.66A4.4 4.4 0 0021.5 4.33c-.833.495-1.667.825-2.583.99a4.053 4.053 0 00-3-1.32c-2.25 0-4.084 1.814-4.084 4.041 0 .33 0 .66.084.907-3.5-.165-6.5-1.814-8.5-4.288-.417.66-.584 1.32-.584 2.062 0 1.402.75 2.639 1.834 3.381-.667 0-1.334-.165-1.834-.495v.083c0 1.98 1.417 3.629 3.25 3.958-.333.083-.666.165-1.083.165-.25 0-.5 0-.75-.082.5 1.65 2 2.804 3.833 2.804C6.667 17.608 4.917 18.268 3 18.268c-.333 0-.667 0-1-.082C3.833 19.34 6 20 8.25 20c7.583 0 11.667-6.186 11.667-11.546v-.495c.833-.578 1.5-1.32 2.083-2.062z"
fill="currentColor"
/>
</svg>
</template>

View File

@ -0,0 +1,3 @@
<template>
<svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M4.71 1h30.58C37.338 1 39 2.661 39 4.71v30.58A3.71 3.71 0 0135.29 39H4.71A3.711 3.711 0 011 35.29V4.71C1 2.662 2.662 1 4.71 1zm19.817 30.354v-.147l-.14.033c.046.039.093.077.14.114zm0 0v3.564c.602.312 1.336.542 2.153.698.816.156 1.707.23 2.597.23.891 0 1.707-.082 2.524-.253a6.398 6.398 0 002.078-.816c.601-.393 1.113-.89 1.41-1.559.297-.668.527-1.41.527-2.375 0-.675-.104-1.261-.304-1.78-.2-.52-.49-.966-.89-1.337a5.902 5.902 0 00-1.337-1.039 16.568 16.568 0 00-1.781-.89c-.304-.125-.573-.246-.84-.366a38.461 38.461 0 00-.496-.22c-.386-.194-.72-.387-.965-.58a2.65 2.65 0 01-.63-.623 1.303 1.303 0 01-.223-.742c0-.253.066-.483.2-.69.134-.208.32-.38.557-.528.237-.148.534-.26.89-.341a5.186 5.186 0 011.188-.119c.311 0 .638.023.965.07a8.255 8.255 0 012.078.579c.326.148.63.32.89.512v-3.488a9.16 9.16 0 00-1.855-.483 14.867 14.867 0 00-2.3-.155c-.892 0-1.708.096-2.524.282a5.876 5.876 0 00-2.079.89c-.6.4-1.039.89-1.41 1.559-.348.623-.52 1.336-.52 2.226 0 1.114.32 2.078.966 2.82.638.817 1.633 1.41 2.894 2.005.443.18.841.359 1.229.534l.181.082c.446.2.817.408 1.114.623.319.215.571.453.742.705.185.253.282.55.282.89a1.385 1.385 0 01-.17.668 1.46 1.46 0 01-.528.535 3.012 3.012 0 01-.89.356 5.43 5.43 0 01-1.262.126 6.729 6.729 0 01-2.375-.423 7.036 7.036 0 01-2.086-1.147zm-1.484-9.276h-4.75V35.66h-3.785V22.078h-4.75v-3.043h13.285v3.043z" fill="currentColor" /></svg>
</template>

View File

@ -0,0 +1,3 @@
<template>
<svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M15.29 8.384l-.547 9.368a.436.436 0 00.53.455l3.29-.77a.437.437 0 01.522.516l-.977 4.856a.436.436 0 00.55.51l2.032-.627a.436.436 0 01.551.51l-1.553 7.628c-.097.478.529.738.79.329l.173-.274 9.627-19.495c.16-.327-.117-.7-.47-.63l-3.386.663a.438.438 0 01-.499-.554l.799-2.81 9.253-1.712c.721-.133 1.27.646.912 1.296l-15.963 28.97a.861.861 0 01-1.51.006L3.133 7.646c-.365-.648.182-1.434.906-1.303l11.25 2.04z" fill="currentColor" /></svg>
</template>

View File

@ -0,0 +1,3 @@
<template>
<svg width="26" height="26" viewBox="0 0 26 26" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M0 2L13 24L26 2H16L13 7.3L10 2H0ZM3.5 4H7.271L13 14L18.729 4H22.5L13 20.1L3.5 4Z" fill="currentColor" /></svg>
</template>

View File

@ -0,0 +1,13 @@
<template>
<svg
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
aria-hidden="true"
role="img"
class="iconify iconify--cib"
width="32"
height="32"
preserveAspectRatio="xMidYMid meet"
viewBox="0 0 32 32"
><path d="M28.021 24.161l-11.552 6.505v-5.068l7.198-3.943zm.792-.713V9.839l-4.229 2.432v8.745zm-24.912.713l11.552 6.505v-5.068l-7.198-3.943zm-.792-.713V9.839l4.229 2.432v8.745zm.495-14.49l11.849-6.672v4.901l-7.646 4.188zm24.714 0L16.469 2.286v4.901l7.646 4.188zm-12.865 15.49l-7.099-3.891v-7.703l7.099 4.083zm1.016 0l7.099-3.891v-7.703l-7.099 4.083zM8.833 11.964l7.13-3.901l7.13 3.901l-7.13 4.099z" fill="currentColor" /></svg>
</template>

View File

@ -0,0 +1,58 @@
<template>
<div ref="containerImg" class="absolute top-0 left-0 z-10 w-full h-full select-none pointer-events-none transition-opacity ease-out duration-800" :class="[hidden ? 'opacity-0' : 'opacity-100']">
<img
ref="gem3"
data-speed="1"
loading="lazy"
:src="`/img/home/hero/gem-3.svg`"
class="hidden lg:block absolute left-1/2 -ml-16 top-20"
alt="An image of a green gem from nuxt galaxy"
>
</div>
</template>
<script>
import { defineComponent, ref, onMounted, onBeforeUnmount } from '@nuxtjs/composition-api'
export default defineComponent({
setup () {
const containerImg = ref(null)
const hidden = ref(true)
function parallax (e) {
const images = Array.from(containerImg.value.children)
if (hidden.value) {
hidden.value = false
}
for (const el of images) {
const image = el
const speed = parseInt(image.getAttribute('data-speed'))
const x = (window.innerWidth - e.pageX * speed) / 100
const y = (window.innerHeight - e.pageY * speed) / 100
image.style.transform = `translateX(${x}px) translateY(${y}px)`
}
}
if (process.client) {
const isTouchDevice = (('ontouchstart' in window) || (navigator.maxTouchPoints > 0) || (navigator.msMaxTouchPoints > 0))
if (isTouchDevice) {
onMounted(() => {
setTimeout(() => {
hidden.value = false
}, 200)
})
} else {
onMounted(() => window.addEventListener('mousemove', parallax))
onBeforeUnmount(() => window.removeEventListener('mousemove', parallax))
}
}
return {
hidden,
containerImg,
parallax
}
}
})
</script>

View File

@ -0,0 +1,33 @@
<template>
<div class="overflow-hidden relative mx-auto max-w-8xl">
<HeroParallax />
<div class="flex flex-wrap justify-center py-0 section">
<section class="flex flex-col justify-start w-full px-4 pt-36 pb-52 md:pt-40 lg:pb-56 lg:pt-48 text-center">
<div>
<span class="nuxt-text-highlight">Currently in public beta</span>
</div>
<h1 class="font-normal font-serif text-display-5 xs:text-display-4 md:text-display-3 2xl:text-display-2 my-8">
<Markdown use="title" unwrap="p" />
</h1>
<h2
class="
font-normal
text-body-base
xs:text-body-lg
md:text-body-xl
2xl:text-body-2xl
px-8
sm:px-0
text-secondary-dark
dark:text-cloud-lighter
"
>
<Markdown use="description" unwrap="p" />
</h2>
<p class="text-center mt-2 text-secondary-dark dark:text-cloud-lighter">
<Markdown use="body" unwrap="p" />
</p>
</section>
</div>
</div>
</template>

View File

@ -0,0 +1,73 @@
<template>
<div class="overflow-hidden relative dark:bg-sky-black dark:text-white pt-14 md:pt-18">
<div class="flex flex-wrap justify-center py-0 section d-container-content">
<section class="flex flex-col justify-start w-full px-4 pt-36 pb-48 md:pt-44 lg:pb-56 lg:pt-24 text-center z-20">
<Gem class="block m-x-auto" />
<h1 class="font-normal font-serif text-display-5 xs:text-display-4 md:text-display-3 2xl:text-display-2 mb-6 pt-8">
<Markdown use="title" unwrap="p" />
</h1>
<h2
class="
font-normal
text-body-base
xs:text-body-lg
md:text-body-xl
2xl:text-body-2xl
mb-8
px-8
sm:px-0
dark:text-cloud-lighter
text-cloud-darker
"
>
<Markdown use="description" unwrap="p" />
</h2>
<div
class="
flex flex-col
sm:flex-row
flex-wrap
items-center
justify-center
space-y-3
sm:space-y-0 sm:space-x-3
xl:space-x-4
"
>
<SectionButton
:href="primary.url"
:aria-label="primary.text"
size="lg"
class="dark:bg-sky-black dark:hover:bg-sky-darker hover:bg-cloud-surface"
:icon-left="primary.icon"
>
{{ primary.text }}
</SectionButton>
<Markdown use="secondary-button" unwrap="p" />
</div>
</section>
</div>
</div>
</template>
<script>
export default {
props: {
primary: {
type: Object,
default: () => ({
text: '38K+ GitHub stars',
url: '/https://github.com',
icon: 'IconGitHub'
})
},
secondary: {
type: Object,
default: () => ({
text: 'Getting started',
url: '/docs'
})
}
}
}
</script>

View File

@ -0,0 +1,36 @@
<template>
<div class="relative">
<section class="py-40 text-white light:text-secondary-black">
<NuxtContainer class="flex flex-col items-center">
<div class="flex flex-col w-full items-center col-span-12">
<div class="mb-2">
<span class="text-cloud-dark dark:text-cloud-light font-bold text-lg">{{ category }}</span>
</div>
<h2 class="font-normal text-center font-serif text-display-6 md:text-display-5 2xl:text-display-4 mb-2">
<Markdown use="title" unwrap="p" />
</h2>
<p class="font-normal text-center text-body-base md:text-body-lg 2xl:text-body-xl mb-12">
<Markdown use="description" unwrap="p" />
</p>
<div class="grid grid-cols-1 xs:grid-cols-2 md:grid-cols-3 lg:grid-cols-4">
<slot />
</div>
<Markdown use="bottom" />
</div>
</NuxtContainer>
</section>
</div>
</template>
<script>
import { defineComponent } from '@nuxtjs/composition-api'
export default defineComponent({
props: {
category: {
type: String,
default: 'Category'
}
}
})
</script>

View File

@ -0,0 +1,70 @@
<template>
<component
:is="component"
:to="to"
:aria-label="title"
class="flex flex-col items-center transition duration-200 p-6 rounded-md"
:class="hoverClass"
>
<InjectComponent
:component="image"
class="mb-4 transition duration-200 text-primary group-hover:text-primary-400"
:class="imageClass"
>
<img loading="lazy" :src="image" :alt="`A ${title} image`">
</InjectComponent>
<h3 class="mb-1 text-center text-body-lg lg:text-body-xl font-bold">
{{ title }}
</h3>
<p class="text-center text-sm lg:text-base mb-4">
{{ description }}
</p>
</component>
</template>
<script>
import { defineComponent, computed } from '@nuxtjs/composition-api'
export default defineComponent({
props: {
image: {
type: String,
default: ''
},
imageClass: {
type: String,
default: ''
},
hoverClass: {
type: String,
default: ''
},
title: {
type: String,
default: ''
},
description: {
type: String,
default: ''
},
to: {
type: String,
default: ''
},
linkName: {
type: String,
default: ''
}
},
setup (props) {
const component = computed(() => {
if (props.to && !props.linkName) {
return 'Link'
}
return 'div'
})
return { component }
}
})
</script>

View File

@ -0,0 +1,16 @@
<template>
<DocusContent :document="page" :class="page.bgClass" />
</template>
<script>
import { defineComponent } from '@nuxtjs/composition-api'
export default defineComponent({
props: {
page: {
type: Object,
required: true
}
}
})
</script>

View File

@ -0,0 +1,33 @@
<template>
<AppPage class="min-h-screen-sm relative z-0 h-full -mb-48">
<div class="relative flex flex-col items-center justify-center px-2 sm:px-4 mt-20 lg:mt-32 md:px-0 z-10">
<h1 class="font-serif text-center text-display-6 md:text-display-5 2xl:text-display-4 mb-6">
{{ error.message }}
</h1>
<NuxtLink
to="/"
size="md"
class="text-gray-800 bg-primary hover:bg-primary-400 focus:bg-primary-400 font-medium rounded-md px-4 py-2.5"
>
Go Home
</NuxtLink>
</div>
</AppPage>
</template>
<script>
import { defineComponent } from '@nuxtjs/composition-api'
export default defineComponent({
props: {
error: {
type: Object,
required: true
}
},
head () {
return {
title: this.error.message
}
}
})
</script>

View File

@ -1,6 +0,0 @@
---
layout.aside: true
navigation.hidden: true
navigation.redirect: /get-started/installation
---

View File

@ -1,49 +0,0 @@
# Installation
Getting started with Nuxt3 is straightforward.
💡 Do you want to experience and prepare your project for Nuxt 3 without breaking changes? Check out [Nuxt Bridge](/bridge/intro) page!
## Prerequisites
Before installing Nuxt, you'll need to have a local development environment.
Recommended setup is:
* **Node.js** <sup>*</sup> (latest LTS version) [[Download](https://nodejs.org/en/download/)]
* **Visual Studio Code** [[Download](https://code.visualstudio.com/)]
* **Volar extension** [[Download](https://marketplace.visualstudio.com/items?itemName=johnsoncodehk.volar)]
* **Yarn package manager** [[Download](https://classic.yarnpkg.com/en/docs/install#windows-stable)]
<sup>*</sup> If you already have Node.js installed, check with `node --version` to ensure using `v14` or `v16`.
## Create project
From visual studio code, open an [integrated terminal](https://code.visualstudio.com/docs/editor/integrated-terminal) and use the following command to create a new starter project:
```bash
npx nuxi init my-nuxt3-project
```
Open `my-nuxt3-project` folder in visual studio code:
```bash
code -r my-nuxt3-project
```
Install dependencies using yarn:
```bash
yarn install
```
## Start Development Server
Now you'll be able to use `yarn dev` to start nuxt app in development mode:
```bash
yarn dev -o
```
✨Well done! A browser window should automatically open to `http://localhost:3000`

View File

@ -1,52 +0,0 @@
# Directory Structure
The Nuxt application structure is intended to provide a great starting point for both small and large applications. You are free to organize your application however you like and can create them as and when you need.
### The `app.vue` file
The `app.vue` file, is used as main component for your application ([learn more](/app/app)).
### The `pages/` directory
The `pages/` directory contains your application's views and routes. If it exists, Nuxt reads all the `.vue` files inside this directory and uses them to create the application router ([learn more](/app/pages)).
### The `plugins/` directory
Nuxt will automatically read the files in your `plugins/` directory and load them. ([learn more](/app/plugins)).
### The `server/` directory
The `server/` directory contains API endpoints and server middleware for your project. ([learn more](/server/api)).
### The `components/` directory
The `components/` directory is where you put all your Vue components which can then be imported inside your pages or other components.
### The `assets/` directory
The `assets/` directory contains your uncompiled assets such as your styles or fonts.
### The `static/` directory
The `static/` directory is directly served at server root and contains public files that have to keep their names (e.g. `robots.txt`) _or_ likely won't change (e.g. `favicon.ico`).
### The `nuxt.config` file
The `nuxt.config` (`js` or `ts`) file is the single point of configuration for Nuxt. If you want to add modules or override default settings, this is the place to apply the changes.
### The `package.json` file
The `package.json` file contains all the dependencies and scripts for your application.
### The `yarn.lock` or `package.lock.json` file
This file is automatically generated and keeps exactly installed version of packages. So that next time you or another one wants to try project, will install same versions.
### The `.nuxt` directory
This is the directory used by nuxt to put temporary build files.
### The `.output` directory
When using `nuxt build`, this directory will be created and is meant to be deployed to production server.

View File

@ -0,0 +1,59 @@
# Introduction
## ❓ What is Nuxt?
Is it the first time Learning about Nuxt or want to get familiar to the new Concepts or Nuxt 3, then we recommand to read the [Concepts section](/concepts)
## 🛠️ Prerequisites
Before getting started, please make sure you have installed recommended development software.
* **Node.js**<sup>*</sup> (latest LTS version) 👉 [[Download](https://nodejs.org/en/download/)]
* **Visual Studio Code** 👉 [[Download](https://code.visualstudio.com/)]
* **Volar Extension** 👉 [[Download](https://marketplace.visualstudio.com/items?itemName=johnsoncodehk.volar)]
<sup>*</sup> If you already have Node.js installed, check with `node --version` to ensure using `v14` or `v16`.
## 🌉 Bridge or Nuxt 3
You must decide if you are starting from scratch or upgrading an existing Nuxt 2 project.
### 🌱 I am starting a fresh Nuxt project
- Enjoy using latest Vue 3
- All of new composables are available
- New templating system and conventions are enabled
👉 You can go to the [Installation section](/getting-started/installation).
### ⬆️ I have an existing Nuxt 2 project
If you have an existing Nuxt 2 project, we **strongly recommend** to start migrating your Nuxt 2 project with Bridge module. This way you can try most of new features without opting-in to more breaking changes.
- It is risk-free! You can roll back by just commenting out one line in config
- Makes your project almost ready for nuxt3 migration
- Enjoy new DX improvements without major rewrites for vue3
- Use nitro engine for platform agnostic and optimized deployments
- Help us stabilize nuxt3 and discover flows
- Bridge is more stable than nuxt3 at the moment for migration
👉 You can go to the [Bridge installation section](/getting-started/installation).
### ‍⚖️ Comparation
In the table below, there is a quick comparison between 3 versions of nuxt:
Feature / Version | Nuxt 2 | Nuxt Bridge | Nuxt 3
-------------------------|-----------------|------------------|---------
Stability | 😸 Stable | 😺 Semi Stable | 🙀 Unstable
Performance | 👎 Slower | 👍 Enhanced | 🔥 Fastest
Nitro Engine | ❌ | ✅ | ✅
ESM support | 🌙 Partial | 👍 Better | ✅
TypeScript | ☑️ Opt-in | 🚧 Faster | ✅
Composition API | ⚠️ Deprecated | ✅ | ✅
Components Auto Import | ✅ | ✅ | ✅
`<script setup>` syntax | ❌ | 🚧 Partial | ✅
Auto Imports | ❌ | ✅ | ✅
Webpack | 4 | 4 | 5
Vite | ⚠️ Partial | 🚧 Partial | 🚧 Experimental
Nuxi CLI | ❌ Old | ✅ | ✅

View File

@ -0,0 +1,43 @@
# Installation
Getting started with Nuxt3 is straightforward.
> Please skip this section if want to upgrade an existing Nuxt 2 project and go to [Bridge](/getting-started/bridge) instead.
> Learn more in the [Introduction](/getting-started/introduction).
## ✨ Create a new project
Open a terminal, or from visual studio code, open an [integrated terminal](https://code.visualstudio.com/docs/editor/integrated-terminal) and use the following command to create a new starter project:
```bash
npx nuxi init my-nuxt3-website
```
Open `my-nuxt3-projewebsitect` folder in visual studio code:
```bash
code -r my-nuxt3-website
```
Install dependencies using yarn:
```bash
yarn install
```
## 🚀 Start Development Server
Now you'll be able to use `yarn dev` to start nuxt app in development mode:
```bash
yarn dev -o
```
✨Well done! A browser window should automatically open to `http://localhost:3000`
# Next steps
Once you created your Nuxt 3 application, you are ready to start building you next application.
- Learn about the [Concepts](/concepts)
- Learn more about [Usage](/docs)

View File

@ -0,0 +1,78 @@
# Bridge
Experience Nuxt 3 on existing Nuxt 2 projects
> Please skip this section if starting a new Nuxt 3 project and go to [Installation](/getting-started/installation) instead.
> Learn more in the [Intorduction](/getting-started/introduction).
Bridge, is a forward-compatibility layer as a module that allows you to opt-in and experience many of new Nuxt 3 features.
Using bridge, you can make sure your project is almost ready for Nuxt 3 and have the latest DX experience without major rewrites and risk of breaking changes by adding a simple module.
### **Step 1:** Upgrade to the latest version of Nuxt 2
Remove package lock-file (`package-lock.json` and `yarn.lock`) and use latest `nuxt-edge`:
**package.json**
```diff
- "nuxt": "^2.15.0"
+ "nuxt-edge": "latest"
```
✔️ After upgrade, please make sure both development and production builds are working fine before proceed to the module installation.
### **Step 2:** Install bridge module
Install `@nuxt/bridge-edge` as a devDependency:
```bash
# Using npm
npm install -D @nuxt/bridge@npm:@nuxt/bridge-edge
# Using yarn
yarn add --dev @nuxt/bridge@npm:@nuxt/bridge-edge
```
### **Step 3:** Update `nuxt.config`
Please make sure to avoid any CommonJS syntax such as `module.exports`, `require` or `require.resolve` in config file. It will be soon deprecated and unsupported. You can use static `import`, dynamic `import()` and `export default` instead. Using typescript by renaming to `nuxt.config.ts` is also possible and recommended.
```ts [nuxt.config.js]
import { defineNuxtConfig } from '@nuxt/bridge'
export default defineNuxtConfig({
// Your existing configuration
})
```
### **Step 4:** Avoid CommonJS syntax
Nuxt natively supports TypeScript and ECMAScript modules. In every file make sure to:
- Change `require('lib')` to `import lib from 'lib'` or `await import('lib').then(e => e.default || e)`
- Change `module.exports` to `export default` or `export const`
- Avoid usage of `__dirname` and `__filename` as much as possible
### **Step 5:** Remove incompatible and obsolete modules
- Remove `@nuxt/content` (1.x) a v2 rewrite for nuxt 3 support is planned, or you may also use docus
- Remove `nuxt-vite`: Bridge enables same functionality
- Remove `@nuxtjs/typescript-build`: Bridge enables same functionality
- Remove `@nuxtjs/typescript-runtime` and `nuxt-ts`: Nuxt 2 has built-in runtime support
- Remove `@nuxt/nitro`: Bridge injects same functionality
- Remove `@nuxtjs/composition-api`: Bridge provides a Nuxt 3 compatible composition-api layer and help to remove dependency
### **Step 6:** Ensure everything goes well
✔️ Try with `nuxt dev` and `nuxt build` (or `nuxt generate`) to see if everything goes well.
🐛 Something is wrong? Please report us by creating an issue. Also, you can easily disable bridge in the meantime:
```ts [nuxt.config.js]
import { defineNuxtConfig } from '@nuxt/bridge'
export default defineNuxtConfig({
bridge: false // Temporary disable bridge integration
})
```

View File

@ -0,0 +1,44 @@
# Commands
Nuxi is the new CLI experience for Nuxt 3
Nuxt 3 has two main commands, one to start development server and one to make production assets prepared.
Since Nuxt 3 becomes a dev dependency thanks to the new Nitro server, you only need to add two commands in your `package.json`:
```json
"scripts": {
"dev": "nuxi dev",
"build": "nuxi build",
}
```
Then, you can run each command using `npm run <command>` `yarn <command>`.
## Development Server
To start Nuxt in development mode with hot module replacement on http://localhost:3000:
::code-group
```bash[Yarn]
yarn dev
```
```bash[NPM]
npm run dev
```
::
## Building for production
To build your Nuxt application for production, run:
::code-group
```bash[Yarn]
yarn build
```
```bash[NPM]
npm run build
```
::
Nuxt will create a `.output` directory with all your application, server and dependencies ready to be deployed. Checkout the [deployment](/docs/deployment) section to learn where and how you can deploy a Nuxt application using Nitro.

View File

@ -0,0 +1,106 @@
# Migration
Nuxt 3 migration guide (Work in progress)
## ⬆️ Nuxt 2 to Nuxt 3
At the moment, there is no Nuxt 2 to Nuxt 3 migration guide nor is recommanded to do it due to potentially more changes coming.
We are working to provide a stable migration guide and tooling to make it as smooth as possible. Please check [Bridge](/getting-started/bridge) for the alternative.
Some features have been dropped from Nuxt 2, some yet need to be implemented for Nuxt 3 and some are new in Nuxt 3 (and Bridge).
Noticable and/or Breaking changes with Nuxt 3 other than the requirements of bridge are:
- Vue app templates are rewritten
- Vue upgraded to `3.x`
- Using suspense for async data fetching
- Webpack `5.x` (if not using `vite`)
- Components discovery is rewritten
- Introduced new `App.vue`
- Introduced new `layouts`
- `pages/` directory conventions changed
In table below there is an overall feature comparation table:
Feature / Version | Nuxt 2 | Nuxt 3 | Changes required
--------------------------|---------|----------|------------------
Vue Version | 2 | 3 | Yes
`app.vue` | ❌ | ✅ | -
Assets | ✅ | ✅ | No
Components | ✅ | ✅ | No
Layouts | ✅ | ✅ | Yes
Error Pages | ✅ | 🚧 | Yes
Pages | ✅ | ✅ | Yes
Pages: Dynamic Params | ✅ | ✅ | Yes
Pages: _.vue | ✅ | ✅ | No
Plugins | ✅ | ✅ | Yes (compatible by default)
Store | ✅ | 🚧 | Yes
Transitions | ✅ | 🚧 | ?
Suspense | ❌ | ✅ | -
Options API: `asyncData` | ✅ | 🚧 | ?
Options API: `fetch` | ✅ | 🚧 | ?
### Nuxt Module Compatibility
- All Nuxt 2 modules should be forward compatible with Nuxt 3 as long as they migrate to bridge or if they are already following guidelines
- All (upcoming) modules made with `@nuxt/kit` should be backward compatible with Nuxt 2 projects (even without bridge) as long as they are not depending on a nuxt3/bridge-only feature
### Nuxt Plugin Compatibility
- Most Nuxt 2 plugins should be forward compatible with nuxt3 with a magical compat layer we inject
- Nuxt3 plugins are **not** backward compatible with Nuxt 2
### Vue Compatibility
For plugins and composition API and components, it needs exclusive vue2 or vue3 support from plugins.
By using [vue-demi](https://github.com/vueuse/vue-demi) they should be compatible with both nuxt2 and nuxt3.
## 📦 Module Migration Guide
When users of nuxt3 use your module, a compatible module container layer from `@nuxt/kit` is automatically injected
so as long as your code is following below guidelines, it should continue working as is.
### Test it with `@nuxt/bridge`:
Migrating to `@nuxt/bridge` is the first and most important step for supporting nuxt3.
If you have a fixture in your module, add `@nuxt/bridge` package to its config (same steps as previous section for nuxt2 projects)
### Avoid CommonJS syntax:
Nuxt natively supports TypeScript and ECMAScript Modules. In every file make sure to:
- Change `require('lib')` to `import lib from 'lib'` or `await import('lib').then(e => e.default || e)`
- Change `module.exports` to `export default` or `export const`
- Avoid usage of `__dirname` and `__filename` as much as possible
### Ensure plugins have default export
If you inject a nuxt plugin that does not have `export default` (such as global Vue plugins), ensure you add `export default {}` to the end of it
### Avoid runtime modules
With nuxt3 and nitro project, we started to rethink how the nuxt build process should work and modules hooking into the Nuxt runtime is now considered an anti-pattern and will not work with nuxt3.
Your module should work fine by adding only to `buildModules[]` (instead of `modules[]`):
- Avoid updating `process.env` within nuxt module and reading by a nuxt plugin. Use `runtimeConfig` instead
- (*) Avoid depending on runtime hooks like `vue-renderer:*` for production
- (*) Avoid adding `serverMiddleware` by importing them inside module. Add them by referencing to file path so that they are independent of module context
(*) Unless it is for `nuxt dev` purpose only and guarded with `if (nuxt.options.dev) { }`.
### Add module meta
Ensure your module is exporting meta object.
[TODO]
### Migrate to TypeScript (optional)
While it is not essential, most of nuxt ecosystem is shifting to use TypeScript, it is highly recommended to consider migration.
**Tip:** You can start migration by simply renaming `.js` files, to `.ts`. TypeScript is designed to be progressive!
**Tip:** You can use TypeScript syntax for nuxt 2/3 modules and plugins without any extra dependencies.

View File

@ -0,0 +1,7 @@
---
title: Get Started
layout.aside: true
layout.asideClass: ''
navigation.exclusive: true
navigation.redirect: /getting-started/introduction
---

View File

@ -1,15 +0,0 @@
# App.vue
The new `app.vue` file, is the main component in your Nuxt3 applications.
If you would like to customize the global website entrypoint, you can create `app.vue` in your project directory. Nuxt will automatically detect it and load it as the parent of all other pages within your application. This will be primarily useful for adding code that should be run on every single page of your site (see [page layouts](/app/pages#layouts) creating dynamic layouts).
**Note:** Don't forget to use `<NuxtPage>` component somewhere inside `app.vue`.
```vue [app.vue]
<template>
<div>
<NuxtPage />
</div>
</template>
```

View File

@ -1,33 +0,0 @@
# Data Fetching
Nuxt provides `asyncData` to handle data fetching within you application.
## `asyncData`
Within your pages and components you can use `asyncData` to get access to data that resolves asynchronously.
### Usage
```js
asyncData(key: string, fn: () => Object, options?: { defer: boolean, server: boolean })
```
* **key**: a unique key to ensure that data fetching can be properly de-duplicated across requests
* **fn** an asynchronous function that **must return an object**.
* **options**:
- _defer_: whether to load the route before resolving the async function (defaults to `false`)
- _server_: whether the fetch the data on server-side (defaults to `true`)
Under the hood, `defer: false` uses `<Suspense>` to block the loading of the route before the data has been fetched. Consider using `defer: true` and implementing a loading state instead for a snappier user experience.
### Example
```vue
<script setup>
const { data } = await useAsyncData('time', () => $fetch('/api/count'))
</script>
<template>
Page visits: {{ data.count }}
</template>
```

View File

@ -0,0 +1,2 @@
# An introduction to Nuxt

View File

@ -0,0 +1,55 @@
# Server Engine
Nuxt 3 is powered by a new server engine, code-named "Nitro".
This engine has many benefits:
::list
- Cross-platform support for Node.js, Browsers, service-workers and more
- Serverless support out-of-the-box
- API routes support
- Automatic code-splitting and async-loaded chunks
- Hybrid mode for static + serverless sites
- Development server with hot module reloading
::
## API Layer
Server [API endpoints](/docs/directory-structure/server#api-routes) and [Middleware](/docs/directory-structure/server#server-middleware) are added by Nitro that internally uses [h3](https://github.com/unjs/h3).
There are a number of key features, including:
* Handlers can directly return objects/arrays for an automatically-handled JSON response
* Handlers can return promises, which will be awaited (`res.end()` and `next()` are also supported)
* Helper functions for body parsing, cookie handling, redirects, headers and more
Check out [the h3 docs](https://github.com/unjs/h3) for more information.
::alert{type="info" icon=}
Learn more about the API layer in the [`server/`](/docs/directory-structure/server) directory.
::
## Direct API calls
Nitro allows 'direct' calling of routes via the globally-available `$fetch` helper. This will make an API call to the server if run on the browser, but will simply call the relevant function if run on the server, **saving an additional API call**.
`$fetch` API is using [ohmyfetch](https://github.com/unjs/ohmyfetch), with key features including:
* Automatic parsing of JSON responses (with access to raw response if needed)
* Request body and params are automatically handled, with correct `Content-Type` headers being added
For more information on `$fetch` features, check out [ohmyfetch](https://github.com/unjs/ohmyfetch).
## Standalone Server
Nitro produces a standalone server dist that is independent of `node_modules`.
The server in Nuxt 2 is not standalone, but requires part of nuxt core to be involved running `nuxt start` (with the [`nuxt-start`](https://www.npmjs.com/package/nuxt-start) or [`nuxt`](https://www.npmjs.com/package/nuxt) distributions) or custom programmatic usage, which was fragile and prone to breakage and not suitable for serverless and service-worker environments.
This dist is generated when running `nuxt build` into a [`.output`](/docs/directory-structure/output) directory.
The output is combined with both runtime code to run your Nuxt server in any environment (including experimental browser Service Workers!) and serve you static files, making it a true [hybrid framework](/concepts/hybrid-rendering) for the JAMStack. In addition, a native storage layer is implemented, supporting multi source, drivers and local assets.
::alert{type="info" icon=IconCode}
Checkout the Nitro engine on GitHub: [framework/packages/nitro](https://github.com/nuxt/framework/tree/main/packages/nitro)
::

View File

@ -0,0 +1,7 @@
---
title: Concepts
layout.aside: true
layout.asideClass: ''
navigation.exclusive: true
navigation.redirect: /concepts/introduction
---

View File

@ -0,0 +1,70 @@
# Data Fetching
Nuxt provides `useAsyncData` to handle data fetching within you application.
## `useAsyncData`
Within your pages and components you can use `useAsyncData` to get access to data that resolves asynchronously.
### Usage
```js
useAsyncData(key: string, fn: () => Object, options?: { defer: boolean, server: boolean })
```
* **key**: a unique key to ensure that data fetching can be properly de-duplicated across requests
* **fn** an asynchronous function that **must return an object**.
* **options**:
- _defer_: whether to load the route before resolving the async function (defaults to `false`)
- _server_: whether the fetch the data on server-side (defaults to `true`)
Under the hood, `defer: false` uses `<Suspense>` to block the loading of the route before the data has been fetched. Consider using `defer: true` and implementing a loading state instead for a snappier user experience.
### Example
```vue
<script setup>
const { data } = await useAsyncData('time', () => $fetch('/api/count'))
</script>
<template>
Page visits: {{ data.count }}
</template>
```
### Best practices
As seen in [Concepts > Data fetching](/concepts/data-fetching), the data returned by `useAsyncData` will be stored inside the page payload. This mean that every key returned that is not used in your component will be added to the payload.
**We strongly recommend to only select the keys that you will use in your component.**
Imagine that `/api/mountains/everest` returns the following object:
```json
{
"title": "Mount Everest",
"description": "Mount Everest is Earth's highest mountain above sea level, located in the Mahalangur Himal sub-range of the Himalayas. The ChinaNepal border runs across its summit point",
"height": "8,848 m",
"countries": [
"China",
"Nepal"
],
"continent": "Asia",
"image": "https://upload.wikimedia.org/wikipedia/commons/thumb/f/f6/Everest_kalapatthar.jpg/600px-Everest_kalapatthar.jpg"
}
```
If you plan to only use `title` and `description` in your component, you can select the keys by chaining the result of `$fetch`:
```vue
<script setup>
const { data: mountain } = await useAsyncData('everest', () =>
$fetch('/api/mountains/everest').then(({ title, description }) => ({ title, description }))
)
</script>
<template>
<h1>{{ mountain.title }}</h1>
<p>{{ mountain.description }}</p>
</template>
```

View File

@ -0,0 +1,7 @@
---
title: 'Usage'
layout.aside: true
layout.asideClass: ''
navigation.collapse: true
navigation.redirect: /docs/basics/introduction
---

View File

@ -0,0 +1,16 @@
---
icon: IconDirectory
title: '.nuxt'
head.title: Nuxt directory
---
# Nuxt directory
The `.nuxt` directory is used by Nuxt in development to generate your Vue application.
::alert{type=warning}
You should not touch any files inside since the whole directory will be re-create when running `nuxt dev`
::
This directory is interesting if you want to learn more about the files Nuxt generates based on your directory structure.

View File

@ -1,3 +1,9 @@
# Plugins
---
icon: IconDirectory
title: 'plugins'
head.title: Plugins directory
---
# plugins directory
Nuxt will automatically read the files in your `plugins` directory and load them. You can use `.server` or `.client` in the file name to load a plugin just on server- or client-side.

View File

@ -0,0 +1,9 @@
---
icon: IconDirectory
title: public
head.title: Public directory
---
# Public directory
The `static/` directory is directly served at server root and contains public files that have to keep their names (e.g. `robots.txt`) _or_ likely won't change (e.g. `favicon.ico`).

View File

@ -0,0 +1,74 @@
---
icon: IconDirectory
title: server
head.title: Server directory
---
# Server directory
The server directory is used to create any backend logic for your Nuxt application. It supports HMR and powerful features.
The `server/` directory contains API endpoints and server middleware for your project. ([learn more](/server/api)).
## API Routes
Nuxt will automatically read in any files in the `~/server/api` directory to create API endpoints.
Each file should export a default function that handles api requests. It can return a promise or JSON data directly (or use `res.end()`).
### Examples
#### Hello world
```js [server/api/hello.ts]
export default (req, res) => 'Hello World'
```
See result on http://localhost:3000/api/hello
#### Async function
```js [server/api/async.ts]
export default async (req, res) => {
await someAsyncFunction()
return {
someData: true
}
}
```
**Example:** Using Node.js style
```ts [server/api/node.ts]
import type { IncomingMessage, ServerResponse } from 'http'
export default async (req: IncomingMessage, res: ServerResponse) => {
res.statusCode = 200
res.end('Works!')
}
```
## Server Middleware
Nuxt will automatically read in any files in the `~/server/middleware` to create server middleware for your project.
These files will be run on every request, unlike [API routes](./api) that are mapped to their own routes. This is typically so you can add a common header to all responses, log responses or modify the incoming request object for use later on in the request chain.
Each file should export a default function that will handle a request.
```js
export default async (req, res) => {
req.someValue = true
}
```
There is nothing different about the `req`/`res` objects, so typing them is straightforward.
```ts
import type { IncomingMessage, ServerResponse } from 'http'
export default async (req: IncomingMessage, res: ServerResponse) => {
req.someValue = true
}
```

View File

@ -0,0 +1,23 @@
---
icon: IconFile
title: .gitignore
head.title: Gitignore file
---
# Gitignore file
A `.gitignore` file specifies intentionally untracked files that Git should ignore. Learn more about it on [the git documentation](https://git-scm.com/docs/gitignore).
We recommand to have a `.gitignore` with **at least** this lines inside:
```bash [.gitignore]
# Nuxt dev/build outputs
.output
.nuxt
# Node dependencies
node_modules
yarn.lock
package-lock.json
# System files
*.log
```

View File

@ -0,0 +1,41 @@
---
icon: IconFile
title: app.vue
head.title: App file
---
# App file
The `app.vue` file is the main component in your Nuxt 3 applications.
## Minimal usage
With Nuxt 3, the [`pages/`](/docs/directory-structure/pages) directory is optional, if not present, Nuxt won't include [vue-router](https://next.router.vuejs.org/) dependency. This is useful when working on a landing page or an application that does not need routing.
```vue [app.vue]
<template>
<h1>Hello World!</h1>
</template>
```
## Usage with pages
If you have a [`pages/`](/docs/directory-structure/pages) directory, to display the current page, use the `<NuxtPage>` component:
```vue [app.vue]
<template>
<div>
<NuxtPage/>
</div>
</template>
```
::alert{type=info}
Since Nuxt 3 uses [`<Suspense>`](https://v3.vuejs.org/guide/migration/suspense.html) inside `<NuxtPage>`, we recommend to wrap it into a single root element.
::
::alert{type=warning}
Remember that `app.vue` acts as the main component of your Nuxt application, anything you add in it (JS and CSS) will be global and included in every page.
::
If you want to have the possibility to customize the structure around the page between pages, checkout the [`layouts/`](/docs/directory-structure/layouts). directory

View File

@ -0,0 +1,508 @@
---
icon: IconFile
title: nuxt.config.js
head.title: Nuxt configuration file
---
# Nuxt configuration file
Nuxt can be configured easily with one single file, called `nuxt.config`, it supports both `.js` and `.ts` extension.
```ts
export default {
// My Nuxt config
}
```
Learn more about all the different [config properties](/docs/config)
<!-- GENERATED_CONFIG_DOCS -->
## alias
- **Type**: `object`
- **Version**: 2, 3
- **Default**
```json
{
"~~": "/project",
"@@": "/project",
"~": "/project",
"@": "/project",
"assets": "/project/assets",
"public": "/project"
}
```
> You can improve your DX by defining additional aliases to access custom directories within your JavaScript and CSS.
::alert{type="info"}
**Note**: Within a webpack context (image sources, CSS - but not JavaScript) you _must_ access
your alias by prefixing it with `~`.
::
::alert{type="info"}
**Note**: If you are using TypeScript and want to use the alias you define within
your TypeScript files, you will need to add the aliases to your `paths` object within `tsconfig.json` .
::
**Example**:
```js
import { resolve } from 'pathe'
export default {
alias: {
'images': resolve(__dirname, './assets/images'),
'style': resolve(__dirname, './assets/style'),
'data': resolve(__dirname, './assets/other/data')
}
}
```
<!-- ```html
<template>
<img src="~images/main-bg.jpg">
</template>
<script>
import data from 'data/test.json'
</script>
<style>
// Uncomment the below
//@import '~style/variables.scss';
//@import '~style/utils.scss';
//@import '~style/base.scss';
body {
background-image: url('~images/main-bg.jpg');
}
</style>
``` -->
## buildDir
- **Type**: `string`
- **Version**: 2, 3
- **Default**
```json
"/project/.nuxt"
```
> Define the directory where your built Nuxt files will be placed.
Many tools assume that `.nuxt` is a hidden directory (because it starts with a `.`). If that is a problem, you can use this option to prevent that.
**Example**:
```js
export default {
buildDir: 'nuxt-build'
}
```
## buildModules
- **Type**: `array`
- **Version**: 2, 3
- **Default**
```json
[]
```
> Modules that are only required during development and build time.
Modules are Nuxt extensions which can extend its core functionality and add endless integrations
Each module is either a string (which can refer to a package, or be a path to a file), a tuple with the module as first string and the options as a second object, or an inline module function.
Nuxt tries to resolve each item in the modules array using node require path (in `node_modules`) and then will be resolved from project `srcDir` if `~` alias is used.
::alert{type="info"}
**Note**: Modules are executed sequentially so the order is important.
::
**Example**:
```js
modules: [
// Using package name
'@nuxtjs/axios',
// Relative to your project srcDir
'~/modules/awesome.js',
// Providing options
['@nuxtjs/google-analytics', { ua: 'X1234567' }],
// Inline definition
function () {}
]
```
::alert{type="info"}
**Note**: Using `buildModules` helps to make production startup faster and also significantly
decreases the size of `node_modules` in production deployments. Please refer to each
module's documentation to see if it is recommended to use `modules` or `buildModules`.
::
## dev
- **Type**: `boolean`
- **Version**: 2, 3
- **Default**
```json
true
```
> Whether Nuxt is running in development mode.
Normally you should not need to set this.
## dir
> Customize default directory structure used by nuxt.
It is better to stick with defaults unless needed.
### `layouts`
- **Type**: `string`
- **Version**: 2, 3
- **Default**
```json
"layouts"
```
> The layouts directory, each file of which will be auto-registered as a Nuxt layout.
### `pages`
- **Type**: `string`
- **Version**: 2, 3
- **Default**
```json
"pages"
```
> The directory which will be processed to auto-generate your application page routes.
### `public`
- **Type**: `string`
- **Version**: 3
- **Default**
```json
"public"
```
> The directory containing your static files, which will be directly accessible via the Nuxt server and copied across into your `dist` folder when your app is generated.
## extensions
- **Type**: `array`
- **Version**: 2, 3
- **Default**
```json
[
".js",
".mjs",
".ts",
".tsx",
".vue"
]
```
> The extensions that should be resolved by the Nuxt resolver.
## globalName
- **Type**: `string`
- **Version**: 2, 3
- **Default**
```json
"nuxt"
```
> Allows customizing the global ID used in the main HTML template as well as the main Vue instance name and other options.
## hooks
- **Type**: `any`
- **Version**: 2, 3
- **Default**
```json
null
```
> Hooks are listeners to Nuxt events that are typically used in modules, but are also available in `nuxt.config`.
Internally, hooks follow a naming pattern using colons (e.g., build:done).
For ease of configuration, you can also structure them as an hierarchical object in `nuxt.config` (as below).
**Example**:
```js
import fs from 'fs'
import path from 'path'
export default {
hooks: {
build: {
done(builder) {
const extraFilePath = path.join(
builder.nuxt.options.buildDir,
'extra-file'
)
fs.writeFileSync(extraFilePath, 'Something extra')
}
}
}
}
```
## modules
- **Type**: `array`
- **Version**: 2, 3
- **Default**
```json
[]
```
> Modules are Nuxt extensions which can extend its core functionality and add endless integrations
Each module is either a string (which can refer to a package, or be a path to a file), a tuple with the module as first string and the options as a second object, or an inline module function.
Nuxt tries to resolve each item in the modules array using node require path (in `node_modules`) and then will be resolved from project `srcDir` if `~` alias is used.
::alert{type="info"}
**Note**: Modules are executed sequentially so the order is important.
::
**Example**:
```js
modules: [
// Using package name
'@nuxtjs/axios',
// Relative to your project srcDir
'~/modules/awesome.js',
// Providing options
['@nuxtjs/google-analytics', { ua: 'X1234567' }],
// Inline definition
function () {}
]
```
## privateRuntimeConfig
- **Type**: `any`
- **Version**: 2, 3
- **Default**
```json
{}
```
> Runtime config allows passing dynamic config and environment variables to the Nuxt app context.
It is added to the Nuxt payload so there is no need to rebuild to update your configuration in development or if your application is served by the Nuxt server. (For static sites you will still need to regenerate your site to see changes.)
The value of this object is accessible from server only using `$config`.
It will override `publicRuntimeConfig` on the server-side.
It should hold _private_ environment variables (that should not be exposed on the frontend). This could include a reference to your API secret tokens.
**Example**:
```js
export default {
privateRuntimeConfig: {
apiSecret: process.env.API_SECRET
}
}
```
## publicRuntimeConfig
> Runtime config allows passing dynamic config and environment variables to the Nuxt app context.
It is added to the Nuxt payload so there is no need to rebuild to update your configuration in development or if your application is served by the Nuxt server. (For static sites you will still need to regenerate your site to see changes.)
The value of this object is accessible from both client and server using `$config`. It should hold env variables that are _public_ as they will be accessible on the frontend. This could include a reference to your public URL.
**Example**:
```js
export default {
publicRuntimeConfig: {
baseURL: process.env.BASE_URL || 'https://nuxtjs.org'
}
}
```
### `app`
- **Type**: `object`
- **Version**: 2, 3
- **Default**
```json
{
"basePath": "/",
"assetsPath": "/_nuxt/",
"cdnURL": null
}
```
## rootDir
- **Type**: `string`
- **Version**: 2, 3
- **Default**
```json
"/project"
```
> Define the workspace directory of your application.
This property can be overwritten (for example, running `nuxt ./my-app/` will set the `rootDir` to the absolute path of `./my-app/` from the current/working directory.
It is normally not needed to configure this option.
## serverMiddleware
- **Type**: `array`
- **Version**: 2, 3
- **Default**
```json
[]
```
> Server middleware are connect/express/h3-shaped functions that handle server-side requests. They run on the server and before the Vue renderer.
By adding entries to `serverMiddleware` you can register additional routes or modify `req`/`res` objects without the need for an external server.
You can pass a string, which can be the name of a node dependency or a path to a file. You can also pass an object with `path` and `handler` keys. (`handler` can be a path or a function.)
**Example**:
```js
serverMiddleware: [
// Will register redirect-ssl npm package
'redirect-ssl',
// Will register file from project server-middleware directory to handle /server-middleware/* requires
{ path: '/server-middleware', handler: '~/server-middleware/index.js' },
// We can create custom instances too
{ path: '/static2', handler: serveStatic(__dirname + '/static2') }
]
```
::alert{type="info"}
**Note**: If you don't want middleware to run on all routes you should use the object
form with a specific path.
::
<!-- If you pass a string handler, Nuxt will expect that file to export a default function
that handles `(req, res, next) => void`. -->
**Example**:
```js
export default function (req, res, next) {
// req is the Node.js http request object
console.log(req.url)
// res is the Node.js http response object
// next is a function to call to invoke the next middleware
// Don't forget to call next at the end if your middleware is not an endpoint!
next()
}
```
<!-- Alternatively, it can export a connect/express/h3-type app instance. -->
**Example**:
```js
const bodyParser = require('body-parser')
const app = require('express')()
app.use(bodyParser.json())
app.all('/getJSON', (req, res) => {
res.json({ data: 'data' })
})
module.exports = app
```
<!-- Alternatively, instead of passing an array of `serverMiddleware`, you can pass an object
whose keys are the paths and whose values are the handlers (string or function). -->
**Example**:
```js
export default {
serverMiddleware: {
'/a': '~/server-middleware/a.js',
'/b': '~/server-middleware/b.js',
'/c': '~/server-middleware/c.js'
}
}
```
## srcDir
- **Type**: `string`
- **Version**: 2, 3
- **Default**
```json
"/project"
```
> Define the source directory of your Nuxt application.
If a relative path is specified it will be relative to the `rootDir`.
**Example**:
```js
export default {
srcDir: 'client/'
}
```
This would work with the following folder structure:
```bash
-| app/
---| node_modules/
---| nuxt.config.js
---| package.json
---| client/
------| assets/
------| components/
------| layouts/
------| middleware/
------| pages/
------| plugins/
------| static/
------| store/
```
## ssr
- **Type**: `boolean`
- **Version**: 2, 3
- **Default**
```json
true
```
> Whether to enable rendering of HTML - either dynamically (in server mode) or at generate time. If set to `false` and combined with `static` target, generated pages will simply display a loading screen with no content.
## watchers
> The watchers property lets you overwrite watchers configuration in your `nuxt.config`.
### `chokidar`
> Options to pass directly to `chokidar`.
**See**: [chokidar](https://github.com/paulmillr/chokidar#api)
#### `ignoreInitial`
- **Type**: `boolean`
- **Version**: 2, 3
- **Default**
```json
true
```
### `rewatchOnRawEvents`
- **Type**: `any`
- **Version**: 2, 3
- **Default**
```json
{}
```
> An array of event types, which, when received, will cause the watcher to restart.
### `webpack`
> `watchOptions` to pass directly to webpack.
**See**: [webpack@4 watch options](https://v4.webpack.js.org/configuration/watch/#watchoptions).
#### `aggregateTimeout`
- **Type**: `number`
- **Version**: 2, 3
- **Default**
```json
1000
```

View File

@ -0,0 +1,9 @@
---
icon: IconFile
title: package.json
head.title: Package file
---
# Package file
The `package.json` file contains all the dependencies and scripts for your application ([learn more](/docs/directory-structure/package-json)).

View File

@ -0,0 +1,15 @@
---
icon: IconDirectory
title: '.output'
head.title: Output directory
---
# Output directory
The `.output/` directory is created by Nuxt when building your application for production.
::alert{type=warning}
You should not touch any files inside since the whole directory will be re-create when running `nuxt build`
::
This directory is made to be used when deploying your Nuxt application to production, learn more in our [deployment section](/docs/deployment).

View File

@ -0,0 +1,16 @@
---
icon: IconDirectory
title: 'assets'
head.title: Assets directory
---
# Assets directory
The `assets/` directory is used to add all the website assets that will be processed by the build tool (Webpack of Vite).
The directory usually contain such files:
- Stylesheets (CSS, SASS, etc.)
- Fonts
- Images that won't be served from the [public/](/docs/structure/public) directory.
If you want to serve assets from the server, we recommend to take a look at the [public/](/docs/structure/public) directory.

View File

@ -0,0 +1,9 @@
---
icon: IconDirectory
title: 'components'
head.title: Components directory
---
# Components directory
The `components/` directory is where you put all your Vue components which can then be imported inside your pages or other components ([learn more](/docs/directory-structure/components)).

View File

@ -0,0 +1,9 @@
---
icon: IconDirectory
title: 'composables'
head.title: Composables directory
---
# Composables directory
Nuxt will soon support a `composables/` directory to auto import your Vue composables into your application when used, learn more on the [open issue](https://github.com/nuxt/framework/issues/639).

View File

@ -1,36 +1,16 @@
# Pages
---
icon: IconDirectory
title: 'layouts'
head.title: Layouts directory
---
Nuxt will automatically integrate [Vue Router](https://next.router.vuejs.org/) and map `pages/` directory into the routes of your application.
## Dynamic Routes
If you place anything within square brackets, it will be turned into a [dynamic route](https://next.router.vuejs.org/guide/essentials/dynamic-matching.html) parameter. You can mix and match multiple parameters and even non-dynamic text within a file name or directory.
### Example
```bash
-| pages/
---| index.vue
---| users-[group]/
-----| [id].vue
```
Given the example above, you can access group/id within your component via the `$route` object:
```vue
<template>
{{ $route.params.group }}
{{ $route.params.id }}
</template>
```
## Layouts
# Layouts directory
Nuxt provides a customizable layouts framework you can use throughout your application, ideal for extracting common UI or code patterns into reusable layout components.
Page layouts are placed in the `layouts/` directory and will be automatically loaded via asynchronous import when used. If you create a `layouts/default.vue` this will be used for all pages in your app. Other layouts are used by setting a `layout` property as part of your component options.
If you have only single layout for application, you can alternatively use (app entry)[/app].
If you have only single layout for application, you can alternatively use [app.vue](/docs/structure/app).
### Example: a custom layout

View File

@ -0,0 +1,7 @@
---
icon: IconDirectory
title: 'node_modules'
head.title: Node modules directory
---
# Node modules directory

View File

@ -1,3 +1,13 @@
---
icon: IconDirectory
title: 'modules'
head.title: Local modules directory
---
# Local modules directory
Nuxt has a powerful [modules engine](/concepts/modules).
# Creating Modules
Nuxt provides helper functions (accessed from `@nuxt/kit`) to assist in creating modules that can run on both Nuxt 2 and Nuxt 3.
@ -81,3 +91,5 @@ A number of helpers are also provided for use within this context (with more com
* extendRoutes
Each of these functions provides documentation via IDE hover/autocomplete.
## Publishing to NPM

View File

@ -0,0 +1,33 @@
---
icon: IconDirectory
title: 'pages'
head.title: Pages directory
---
The `pages/` directory is optional, meaning that if you only use [app.vue](/docs/directory-structure/app), vue-router won't be included, reducing your application bundle size.
# Pages directory
Nuxt will automatically integrate [Vue Router](https://next.router.vuejs.org/) and map `pages/` directory into the routes of your application.
## Dynamic Routes
If you place anything within square brackets, it will be turned into a [dynamic route](https://next.router.vuejs.org/guide/essentials/dynamic-matching.html) parameter. You can mix and match multiple parameters and even non-dynamic text within a file name or directory.
### Example
```bash
-| pages/
---| index.vue
---| users-[group]/
-----| [id].vue
```
Given the example above, you can access group/id within your component via the `$route` object:
```vue
<template>
{{ $route.params.group }}
{{ $route.params.id }}
</template>
```

View File

@ -0,0 +1,7 @@
---
title: 'Directory structure'
layout.aside: true
layout.asideClass: ''
navigation.collapse: false
navigation.redirect: /docs/directory-structure/app
---

View File

@ -0,0 +1,9 @@
---
layout:
aside: true
asideClass: ''
navigation:
collapse: true
exclusive: false
redirect: /docs/deployment/platforms
---

View File

@ -12,7 +12,7 @@ Nitro will auto-detect that you are in a Netlify environment and build the corre
## Deployment
Just push to your git repository [as you would normally for Netlify](https://docs.netlify.com/configure-builds/get-started/).
Just push to your git repository [as you would normally for Netlify](https://docs.netlify.com/configure-builds/getting-started/).
## More information

View File

@ -1,8 +1,8 @@
# Presets (advanced)
# [Presets]
There are four provided generic presets for Nuxt Nitro that you can use out-of-the-box:
There are four provided generic presets for Nuxt Nitro that you can use out-of-the-box.
1. [Node.js server](/deployment/presets/server)
1. [Node.js server *(default)*](/deployment/presets/server)
2. [Node.js function](/deployment/presets/node)
3. [Lambda function](/deployment/presets/lambda)
4. [Service worker](/deployment/presets/service-worker)

View File

@ -0,0 +1,63 @@
# Node.js server
:ok_hand: **Default preset** if none is specified or auto-detected <br>
:rocket: Loads only the required chunks to render the request for optimal cold start timing <br>
:bug: Useful for debugging
### Usage
You can use the [Nuxt config](/config) to explicity set the preset to use:
```ts [nuxt.config.js|ts]
export default {
nitro: {
preset: 'server'
}
}
```
Or directly use the `NITRO_PRESET` environment variable when running `nuxt build`:
```bash
NITRO_PRESET=server npx nuxt build
```
### Entrypoint
When running `nuxt build` with the Node server preset, the result will be an entrypoint that launches a ready-to-run Node server.
```bash
node .output/server/index.mjs
```
### Example
```bash
$ node .output/server/index.mjs
Listening on http://localhost:3000
```
### Server timings
You can enable the `nitro.timing` option in order to have the logs about the chunk loading and cold start performance.
```ts [nuxt.config.js|ts]
export default {
nitro: {
preset: 'server',
timing: true
}
}
```
```bash
$ node .output/server/index.mjs
> Cold Start (3ms)
Listening on http://localhost:3000
> Load chunks/nitro/static (0ms)
> Load chunks/app/render (1ms)
> Load chunks/app/client.manifest (0ms)
> Load chunks/index (3ms)
> Load chunks/app/server (2ms)
> Load chunks/app/vue3 (0ms)
```

Some files were not shown because too many files have changed in this diff Show More