Skip to content

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 ​

sh
bun add vitepress vue scavold

Or with npm:

sh
npm install vitepress vue scavold

2. 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.json

3. .cratly.config.yaml ​

Scavold reads site structure from this file at the project root.

yaml
version: 0

pages_folder: pages
media_folder: media
static_folder: public

augmentConfig() reads these paths and wires them into VitePress automatically — you do not need to set srcDir or vite.publicDir manually.

4. .vitepress/config.js ​

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 function

Setting 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:

js
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. Its second argument takes options for the theme; gridImageSizes sets the image sizes in a grid by column count.

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:

js
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.

vue
<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 ​

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 ​

json
{
  "scripts": {
    "dev":     "bunx --bun vitepress dev",
    "build":   "bunx --bun vitepress build",
    "preview": "bunx --bun vitepress preview"
  }
}

9. Run ​

sh
bun run dev

VitePress starts the dev server. Changes to Markdown files hot-reload automatically.


Next steps ​