feat: Complete fleet — 94 skills across 10+ domains
Pulled ALL skills from 15 source repositories: - anthropics/skills: 16 (docs, design, MCP, testing) - obra/superpowers: 14 (TDD, debugging, agents, planning) - coreyhaines31/marketingskills: 25 (marketing, CRO, SEO, growth) - better-auth/skills: 5 (auth patterns) - vercel-labs/agent-skills: 5 (React, design, Vercel) - antfu/skills: 16 (Vue, Vite, Vitest, pnpm, Turborepo) - Plus 13 individual skills from various repos Mosaic Stack is not limited to coding — the Orchestrator and subagents serve coding, business, design, marketing, writing, logistics, analysis, and more. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
269
skills/vitepress/references/theme-custom.md
Normal file
269
skills/vitepress/references/theme-custom.md
Normal file
@@ -0,0 +1,269 @@
|
||||
---
|
||||
name: vitepress-custom-themes
|
||||
description: Building custom themes from scratch with the theme interface, Layout component, and enhanceApp
|
||||
---
|
||||
|
||||
# Custom Themes
|
||||
|
||||
Build a theme from scratch when the default theme doesn't fit your needs.
|
||||
|
||||
## Theme Entry
|
||||
|
||||
Create `.vitepress/theme/index.ts`:
|
||||
|
||||
```ts
|
||||
// .vitepress/theme/index.ts
|
||||
import Layout from './Layout.vue'
|
||||
|
||||
export default {
|
||||
Layout,
|
||||
enhanceApp({ app, router, siteData }) {
|
||||
// Register global components, plugins, etc.
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Theme Interface
|
||||
|
||||
```ts
|
||||
interface Theme {
|
||||
// Required: Root layout component
|
||||
Layout: Component
|
||||
|
||||
// Optional: Enhance Vue app instance
|
||||
enhanceApp?: (ctx: EnhanceAppContext) => Awaitable<void>
|
||||
|
||||
// Optional: Extend another theme
|
||||
extends?: Theme
|
||||
}
|
||||
|
||||
interface EnhanceAppContext {
|
||||
app: App // Vue app instance
|
||||
router: Router // VitePress router
|
||||
siteData: Ref<SiteData> // Site-level metadata
|
||||
}
|
||||
```
|
||||
|
||||
## Basic Layout
|
||||
|
||||
The Layout component must render `<Content />` for markdown:
|
||||
|
||||
```vue
|
||||
<!-- .vitepress/theme/Layout.vue -->
|
||||
<script setup>
|
||||
import { useData } from 'vitepress'
|
||||
const { page, frontmatter } = useData()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="layout">
|
||||
<header>
|
||||
<nav>My Site</nav>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<div v-if="page.isNotFound">
|
||||
<h1>404 - Page Not Found</h1>
|
||||
</div>
|
||||
|
||||
<div v-else-if="frontmatter.layout === 'home'">
|
||||
<h1>Welcome!</h1>
|
||||
</div>
|
||||
|
||||
<article v-else>
|
||||
<Content />
|
||||
</article>
|
||||
</main>
|
||||
|
||||
<footer>
|
||||
<p>© 2024 My Site</p>
|
||||
</footer>
|
||||
</div>
|
||||
</template>
|
||||
```
|
||||
|
||||
## Runtime API
|
||||
|
||||
Access VitePress data in your theme:
|
||||
|
||||
```vue
|
||||
<script setup>
|
||||
import { useData, useRoute, useRouter } from 'vitepress'
|
||||
|
||||
// Page and site data
|
||||
const {
|
||||
site, // Site config (title, description, etc.)
|
||||
theme, // Theme config
|
||||
page, // Current page data
|
||||
frontmatter, // Current page frontmatter
|
||||
title, // Page title
|
||||
description, // Page description
|
||||
lang, // Current language
|
||||
isDark, // Dark mode state
|
||||
params // Dynamic route params
|
||||
} = useData()
|
||||
|
||||
// Routing
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
|
||||
// Navigate programmatically
|
||||
const goToGuide = () => router.go('/guide/')
|
||||
</script>
|
||||
```
|
||||
|
||||
## Built-in Components
|
||||
|
||||
```vue
|
||||
<script setup>
|
||||
import { Content } from 'vitepress'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<!-- Renders markdown content -->
|
||||
<Content />
|
||||
|
||||
<!-- Renders slot only on client (SSR-safe) -->
|
||||
<ClientOnly>
|
||||
<NonSSRComponent />
|
||||
</ClientOnly>
|
||||
</template>
|
||||
```
|
||||
|
||||
## Extend Another Theme
|
||||
|
||||
Build on top of default theme or any other:
|
||||
|
||||
```ts
|
||||
// .vitepress/theme/index.ts
|
||||
import DefaultTheme from 'vitepress/theme'
|
||||
|
||||
export default {
|
||||
extends: DefaultTheme,
|
||||
enhanceApp({ app }) {
|
||||
// Your customizations
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Register Plugins and Components
|
||||
|
||||
```ts
|
||||
// .vitepress/theme/index.ts
|
||||
import Layout from './Layout.vue'
|
||||
import GlobalComponent from './GlobalComponent.vue'
|
||||
|
||||
export default {
|
||||
Layout,
|
||||
enhanceApp({ app }) {
|
||||
// Register global component
|
||||
app.component('GlobalComponent', GlobalComponent)
|
||||
|
||||
// Register plugin
|
||||
app.use(MyPlugin)
|
||||
|
||||
// Provide/inject
|
||||
app.provide('key', value)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Async enhanceApp
|
||||
|
||||
For plugins that need async initialization:
|
||||
|
||||
```ts
|
||||
export default {
|
||||
Layout,
|
||||
async enhanceApp({ app }) {
|
||||
if (!import.meta.env.SSR) {
|
||||
// Client-only plugin
|
||||
const plugin = await import('browser-only-plugin')
|
||||
app.use(plugin.default)
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Theme-Aware Layout
|
||||
|
||||
Handle different page layouts:
|
||||
|
||||
```vue
|
||||
<script setup>
|
||||
import { useData } from 'vitepress'
|
||||
import Home from './Home.vue'
|
||||
import Doc from './Doc.vue'
|
||||
import Page from './Page.vue'
|
||||
import NotFound from './NotFound.vue'
|
||||
|
||||
const { page, frontmatter } = useData()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<NotFound v-if="page.isNotFound" />
|
||||
<Home v-else-if="frontmatter.layout === 'home'" />
|
||||
<Page v-else-if="frontmatter.layout === 'page'" />
|
||||
<Doc v-else />
|
||||
</template>
|
||||
```
|
||||
|
||||
## Distributing a Theme
|
||||
|
||||
As npm package:
|
||||
|
||||
```ts
|
||||
// my-theme/index.ts
|
||||
import Layout from './Layout.vue'
|
||||
export default { Layout }
|
||||
|
||||
// Export types for config
|
||||
export type { ThemeConfig } from './types'
|
||||
```
|
||||
|
||||
Consumer usage:
|
||||
|
||||
```ts
|
||||
// .vitepress/theme/index.ts
|
||||
import Theme from 'my-vitepress-theme'
|
||||
|
||||
export default Theme
|
||||
|
||||
// Or extend it
|
||||
export default {
|
||||
extends: Theme,
|
||||
enhanceApp({ app }) {
|
||||
// Additional customization
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Theme Config Types
|
||||
|
||||
For custom theme config types:
|
||||
|
||||
```ts
|
||||
// .vitepress/config.ts
|
||||
import { defineConfigWithTheme } from 'vitepress'
|
||||
import type { ThemeConfig } from 'my-theme'
|
||||
|
||||
export default defineConfigWithTheme<ThemeConfig>({
|
||||
themeConfig: {
|
||||
// Type-checked theme config
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
## Key Points
|
||||
|
||||
- Theme must export `Layout` component
|
||||
- `<Content />` renders the markdown content
|
||||
- Use `useData()` to access page/site data
|
||||
- `enhanceApp` runs on both server and client
|
||||
- Check `import.meta.env.SSR` for client-only code
|
||||
- Use `extends` to build on existing themes
|
||||
|
||||
<!--
|
||||
Source references:
|
||||
- https://vitepress.dev/guide/custom-theme
|
||||
-->
|
||||
Reference in New Issue
Block a user