In this section, we'll cover the basics to start building an application.
src/
โโโ components/
โ โโโ ReadingTime.vue
โ โโโ Author.vue
โ
โโโ layouts/
โ โโโ default.vue
โ โโโ post.vue
โ
โโโ pages/
โ โโโ posts/
โ โ โโโ intro.mdx
โ โ โโโ goodbye.mdx
โ โโโ about.vue
โ โโโ index.mdx
โ
โโโ site.ts
โโโ app.ts
srcDir is the src
directory at your project root, and is aliased as ~/
or @/
.
For example:
// Named import from `src/utils/index.ts`
import { camelize } from '~/utils'
<!-- Asset import of src/assets/logo.svg -->
<img src="@/assets/logo.svg"/>
รles auto-imports APIs on-demand, powered by unplugin-auto-import in the following file extensions.
.vue
, .md
, .mdx
, .ts
, .tsx
, .js
, .jsx
, .svelte
The auto-imported APIs includes:
vue
APIs: ref
, computed
, reactive
, etc.รles
composables: usePage
, useRoute
, definePageComponent
, useDocuments
.@unhead/vue
composables: useHead
, useSeoMeta
, useScript
, etc.src/composables
folder.To illustrate, the imports in the below example are not required.
<script setup lang="ts">
import { computed } from 'vue' // not required
import { usePage } from 'iles' // not required
import { useHead } from '@unhead/vue' // not required
import { isDark, toggleDark } from '@/composables/dark' // not required
const toggleTheme = () => {
// Trigger with button click in the template
toggleDark()
}
const { frontmatter, site, route } = usePage()
const { title: pageTitle, description } = frontmatter
const { title: siteTitle, titleSeparator } = site
const canonicalUrl = new URL(route.path, site.url)
useHead({
title: pageTitle
? `${pageTitle} ${titleSeparator} ${siteTitle}`
: siteTitle,
meta: [
{
name: 'description',
content: description,
},
],
link: [
{
rel: 'canonical',
href: canonicalUrl.href,
},
],
})
const navs = [
{ title: 'Home', to: '/' },
{ title: 'About', to: '/about' },
]
const currentPath = computed(() => {
return route.path
})
</script>
Use the
autoImport
key iniles.config.ts
to customize Auto Import configurations.
Auto Import also supports presets and resolvers for popular libraries such as
vue-i18n
,@vueuse/core
,pinia
,primevue
, etc.
Components in the src/components directory will be auto-imported on-demand, powered by unplugin-vue-components
.
รles extends this so that you don't need to import components in MDX files.
Use the
components
key iniles.config.ts
to customize Auto Import configurations for components.
Auto Import configurations for components also includes options such as extensions, directories to scan, resolvers etc.
Components in the src/layouts directory will be available as layouts, and they should provide a default <slot/>
.
Pages may specify a layout using the layout
property in frontmatter:
---
layout: post
---
Layouts and Vue pages can also specify a parent layout using a layout
attribute in the template
:
<template layout="post">
Layouts are optional; however, having a default layout is highly recommended.
The
default
layout will be used for all pages unless specified.Pages may opt-out by specifying
layout: false
Layout files must be in lowercase, as in
post.vue
ordefault.vue
.
Routes will be auto-generated for files in the src/pages directory with the same file structure.
Pages can be Vue components or MDX files, and may specify frontmatter and route metadata.
You may use components inside MDX, and access any properties defined in the frontmatter:
---
title: Song for You
audio: /song-for-you.mp3
---
I've recently recorded a song, listen:
<Song title={title} src={audio}/>
In Vue single-file components you can use a <page>
block to define frontmatter:
<page>
title: Song for You
audio: /song-for-you.mp3
</page>
<template>
<p>I've recently recorded a song, listen:</p>
<Song :title="$frontmatter.title" :src="$frontmatter.audio"/>
</template>
Page Hooks ๐ฃYou can customize all pages using the extendFrontmatter and extendRoute hooks.
You may access information about the current page using the usePage
composition API helper, or by using the $frontmatter
or $meta
global properties.
frontmatter
: The frontmatter of an MDX document or Vue component (in <page>
)meta
: Information about the page, including href
, filename
, and lastUpdated
<script setup>
import { usePage } from 'iles' // not required
const { frontmatter, meta } = usePage()
</script>
Auto-imported APIs and ComposablesYou don't need to import ref, computed, reactive, usePage, useRoute, definePageComponent, useDocuments, useHead, useSeoMeta, useScript.
When rendering collections or index pages, you can leverage useDocuments to conveniently access multiple page components and their data.
export function usePosts () {
const posts = useDocuments('~/pages/posts')
return computed(() => posts.value.sort(byDate))
}
Page data is available directly in the component modules:
<script setup lang="ts">
import { usePosts } from '~/composables/posts'
const posts = usePosts()
</script>
<template>
<h1>Posts</h1>
<article v-for="post of posts" :key="post.href">
<time :datetime="post.date.toISOString()">{{ formatDate(post.date) }}</time>
<h2>
<a :href="post.href">{{ post.title }}</a>
</h2>
<component :is="post" excerpt/>
</article>
</template>
src/site.ts
can be used to provide site-wide information such as title
, description
, etc.
export default {
title: 'About',
description: 'Learn more about what we do',
}
It can be accessed as $site
in component instances, or by using usePage
.
<script setup>
import { usePage } from 'iles' // not required
const { site } = usePage()
</script>
It's also displayed in the page information in Islands devtools.
Adding
src/site.ts
to your project is optional.Alternatively, you can use composables from
@unhead/vue
to manage the head and meta tags of your page.
will pre-configure a Vue 3 shell that, during development, will load your site comprising of your layouts and pages within it.
src/app.ts
can be used to provide additional configurations with the defineApp
helper, allowing you to customize:
enhanceApp
, the development and build logic of this "outer" shell.enhanceIslands
, add Vue plugins and top level runtime logic in your Vue Islands.This "outer" shell is loaded only during development and is not included in your built site.
Adding
src/app.ts
to your project is optional.
import { defineApp } from 'iles'
export default defineApp({
enhanceApp ({ app, head, router }) {
// Configure the "outer" shell to customize it's development/build logic
},
enhanceIslands ({ app }) {
// Configure Vue Islands with plugins and other top level runtime logic
},
head ({ frontmatter, site }) {
return {
meta: [
{ property: 'author', content: site.author },
{ property: 'keywords', content: computed(() => frontmatter.tags) },
]
}
},
router: {
scrollBehavior (current, previous, savedPosition) {
// Configure the scroll behavior
},
},
mdxComponents: {
// Options for tag mapping in MDX
},
socialTags: true // default
})
enhanceApp
(Development only)(context: AppContext) => void | Promise<void>
A hook that allows you to add additional development/build logic. See this discussion thread for few suggestions.
enhanceIslands
(Vue Islands only)(context: IslandContext) => void | Promise<void>
A hook that allows you to extend your Vue Islands with plugins such as Pinia, i18n, Vuetify, and more, along with any other top-level runtime logic on your site.
The hook will be invoked for every Vue Island in your site.
import { defineApp } from 'iles'
import { createI18n } from 'vue-i18n'
import { createPinia } from 'pinia'
import { createVuetify } from 'vuetify'
const i18n = createI18n({
// vue-i18n options ...
})
const pinia = createPinia()
const vuetify = createVuetify({
// vuetify options ...
})
export default defineApp({
enhanceIslands({ app }) {
app.use(i18n)
app.use(pinia)
if(app._component.name === 'Island: ChatboxIsland') {
// To initialise Vuetify only within ChatboxIsland.vue
app.use(vuetify)
}
},
})
head
HeadObject | (context: AppContext) => HeadObject
Set the head and meta tags, additional CSS, or scripts using @unhead/vue
.
router
RouterOptions
Configure vue-router
by providing options such as scrollBehavior
and linkActiveClass
.
mdxComponents
MDXComponents | (context: AppContext) => MDXComponents
Provide an object that maps tag names in MDX to components to render.
import { defineApp } from 'iles'
import Image from '~/components/Image.vue'
export default defineApp({
mdxComponents: {
b: 'strong',
img: Image,
},
})
socialTags
boolean
true
Some social tags can be inferred from the site.
Set it to false
to avoid adding social tags such as og:title
and twitter:description
.
Page information is available in a debug panel, similar to VitePress, but you may also access an Islands inspector in Vue devtools.
This can be useful when debugging islands hydration.
You may provide a iles.config.ts
configuration file at your project root to customize the various รฎles-specific features.
You may also provide a vite.config.ts
configuration file (or use the vite
key in iles.config.ts
) to add vite plugins and customize the various vite-specific features.
A sitemap can be automatically generated when you build your site, all you need to do is configure siteUrl in your iles.config.ts
configuration file.
If configured, siteUrl
will also make it available as site.url
and site.canonical
.
import { defineConfig } from 'iles'
export default defineConfig({
siteUrl: 'https://nuraui.com',
})
If you would like to opt-out, you can disable it explicitly:
export default defineConfig({
ssg: {
sitemap: false
},
})
To learn more about further Iles and Vite configurations, refer to the config page.