Quick Start
This guide walks you through setting up a new VitePress site using Scavold as its theme base.
Prerequisites
- Bun (recommended) or Node.js ≥ 18
- A new or existing project directory
1. Install dependencies
bun add vitepress vue scavoldOr with npm:
npm install vitepress vue scavold2. Folder layout
Create the following structure:
my-site/
.vitepress/
theme/
index.js ← theme entry point
Layout.vue ← root layout component
style.css ← site styles
config.js ← VitePress + Scavold config
pages/ ← Markdown content
index.md
media/ ← source images and videos
public/ ← static assets served at site root
.cratly.config.yaml
.gitignore
package.json3. .cratly.config.yaml
Scavold reads site structure from this file at the project root.
version: 0
pages_folder: pages
media_folder: media
static_folder: publicaugmentConfig() reads these paths and wires them into VitePress automatically — you do not need to set srcDir or vite.publicDir manually.
4. .vitepress/config.js
import { defineConfig } from "vitepress";
import { augmentConfig } from "scavold/config";
export default defineConfig( await augmentConfig( {
title: "My site",
description: "…",
vite: {
ssr: {
noExternal: [ "scavold" ],
},
},
} ) );Why vite.ssr.noExternal?
Scavold's theme entry (lib/index.js) uses import.meta.glob to auto-register all its Vue components. That is a Vite-specific transform that only runs on files Vite processes as source. When a package is installed in node_modules Vite normally treats it as a pre-built external module and skips the transform — causing the SSR render to fail with:
import.meta.glob is not a functionSetting noExternal: ["scavold"] tells Vite's SSR bundler to process Scavold as source rather than loading it as-is. The glob is then resolved correctly at build time relative to the package's own components/ directory.
5. .vitepress/theme/index.js
Scavold uses @cepharum/vue3-i18n for its own UI strings (breadcrumb labels, locale switcher, etc.) under the @scavold namespace. scavoldEnhanceApp sets this namespace up automatically — you do not need to configure anything for Scavold's own strings to work.
If your site has no custom translated strings of its own, the minimal setup is:
import Layout from "./Layout.vue";
import { enhanceApp as scavoldEnhanceApp } from "scavold";
import "./style.css";
export default { Layout, enhanceApp: scavoldEnhanceApp };If you write your own enhanceApp function — for any reason, not just i18n — await scavoldEnhanceApp first. It registers all Scavold components globally, so anything that depends on those components being available must come after it.
If you want to add your own translated UI strings using the same @cepharum/vue3-i18n library, register a loader for your site's namespace in addition:
import Layout from "./Layout.vue";
import { enhanceApp as scavoldEnhanceApp } from "scavold";
import { useL10n } from "@cepharum/vue3-i18n";
import "./style.css";
async function enhanceApp( context ) {
await scavoldEnhanceApp( context );
useL10n().setLoader( locale =>
import( `./l10n/${locale}.json` ).catch( () => import( "./l10n/en.json" ) )
);
}
export default { Layout, enhanceApp };You are not required to use @cepharum/vue3-i18n for your site's own strings — any other i18n library works alongside Scavold's internal use of it without conflict.
6. .vitepress/theme/Layout.vue
Wrap your site shell in <ScavoldLayout> to get locale redirect handling for free. All Scavold components are globally registered so no explicit imports are needed.
<script setup>
import { useData } from "vitepress";
const { frontmatter } = useData();
</script>
<template>
<ScavoldLayout>
<header>
<ScavoldMenu :from-root="1" label="Main navigation" />
<ScavoldLocaleMenu />
</header>
<main id="main-content">
<ScavoldBreadcrumb />
<Content />
</main>
<footer>
<!-- site footer -->
</footer>
</ScavoldLayout>
</template>7. .gitignore
node_modules
.vitepress/cache
.vitepress/dist
# generated responsive image variants
public/media/**/*--*w-????????.*The glob pattern for generated image variants keeps the source images in version control while excluding the derived variants that Scavold regenerates on every build.
8. package.json scripts
{
"scripts": {
"dev": "bunx --bun vitepress dev",
"build": "bunx --bun vitepress build",
"preview": "bunx --bun vitepress preview"
}
}9. Run
bun run devVitePress starts the dev server. Changes to Markdown files hot-reload automatically.
Next steps
- Component reference — all props, slots, and composables
- Front matter reference — all recognised frontmatter keys
- Configuration reference —
augmentConfigoptions and.cratly.config.yamlschema