Skip to content

Commit c28b146

Browse files
authored
Migrate site from VuePress to VitePress (#311)
Squash-merge of PR #311: migrates the documentation site from VuePress to VitePress — theme and components, dark-mode diagram variants, homepage refresh, and content/link fixes. Full commit-by-commit history is preserved on the PR.
1 parent b12b1c5 commit c28b146

198 files changed

Lines changed: 8796 additions & 2394 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.github/workflows/build.yml‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,13 @@ jobs:
2626
- name: Install
2727
run: npm ci
2828
- name: Build
29-
run: npm run build
29+
run: npm run build:vitepress
3030
# Deploy, limited to the main branch
3131
- name: Deploy
3232
if: success() && github.ref == 'refs/heads/main'
3333
uses: peaceiris/actions-gh-pages@v4
3434
with:
35-
publish_dir: ./docs/.vuepress/dist
35+
publish_dir: ./docs/.vitepress/dist
3636
github_token: ${{ secrets.GITHUB_TOKEN }}
3737
cname: lightningdevkit.org
3838
user_name: 'github-actions[bot]'

‎.gitignore‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33

44
# Production
55
/docs/.vuepress/dist
6+
/docs/.vitepress/dist
7+
/docs/.vitepress/cache
68

79
# Local planning artifacts (Claude /ce workflow)
810
/docs/brainstorms

‎docs/.vitepress/config.mts‎

Lines changed: 225 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,225 @@
1+
import path from 'node:path'
2+
import { fileURLToPath } from 'node:url'
3+
import { defineConfig, type DefaultTheme } from 'vitepress'
4+
5+
const __dirname = path.dirname(fileURLToPath(import.meta.url))
6+
7+
// VuePress 1 still occupies the top-level `node_modules/vue` slot (Vue 2.7.x).
8+
// Force Vite to resolve `vue` and `vue/*` from VitePress's nested Vue 3.
9+
// Remove this alias once VuePress is dropped in Phase 7b.
10+
const vitepressVueDir = path.resolve(
11+
__dirname,
12+
'../../node_modules/vitepress/node_modules/vue',
13+
)
14+
15+
const githubUrl = 'https://github.com/lightningdevkit'
16+
const discordUrl = 'https://discord.gg/5AcknnMfBw'
17+
18+
const blogSidebar: DefaultTheme.SidebarItem[] = [
19+
{
20+
text: 'Blog',
21+
collapsed: false,
22+
items: [
23+
{ text: 'Articles', link: '/blog/' },
24+
{ text: 'Tags', link: '/blog/tags/' },
25+
{ text: 'Authors', link: '/blog/author/' },
26+
],
27+
},
28+
]
29+
30+
const docsSidebar: DefaultTheme.SidebarItem[] = [
31+
{
32+
text: 'Documentation',
33+
collapsed: false,
34+
items: [
35+
{
36+
text: 'Introduction',
37+
link: '/introduction/',
38+
collapsed: true,
39+
items: [
40+
{ text: 'Use Cases', link: '/introduction/use-cases' },
41+
{ text: 'Architecture', link: '/introduction/architecture' },
42+
{ text: 'Peer Management', link: '/introduction/peer-management' },
43+
{ text: 'Persistent Storage', link: '/introduction/persistent_storage' },
44+
{ text: 'Blockchain Data', link: '/introduction/blockchain_data' },
45+
{ text: 'Wallet Management', link: '/introduction/wallet_management' },
46+
{ text: 'Networking', link: '/introduction/networking' },
47+
{ text: 'Private Key Management', link: '/introduction/private_key_management' },
48+
{ text: 'Transactions', link: '/introduction/transactions' },
49+
{ text: 'Random Number Generation', link: '/introduction/random_number_generation' },
50+
],
51+
},
52+
{
53+
text: 'Building a node with LDK',
54+
collapsed: true,
55+
items: [
56+
{ text: 'Introduction', link: '/building-a-node-with-ldk/introduction' },
57+
{ text: 'Installation', link: '/building-a-node-with-ldk/installation' },
58+
{ text: 'Setting up a Channel Manager', link: '/building-a-node-with-ldk/setting-up-a-channel-manager' },
59+
{ text: 'Handling Events', link: '/building-a-node-with-ldk/handling-events' },
60+
{ text: 'Setting up a Peer Manager', link: '/building-a-node-with-ldk/setting-up-a-peer-manager' },
61+
{ text: 'Connect to Peers', link: '/building-a-node-with-ldk/connect-to-peers' },
62+
{ text: 'Opening a Channel', link: '/building-a-node-with-ldk/opening-a-channel' },
63+
{ text: 'Sending Payments', link: '/building-a-node-with-ldk/sending-payments' },
64+
{ text: 'Receiving Payments', link: '/building-a-node-with-ldk/receiving-payments' },
65+
{ text: 'Closing a Channel', link: '/building-a-node-with-ldk/closing-a-channel' },
66+
],
67+
},
68+
{ text: 'Running a sample LDK node', link: '/running-a-sample-ldk-node' },
69+
{
70+
text: 'Advanced Guides',
71+
collapsed: true,
72+
items: [
73+
{ text: 'Blockchain Data', link: '/blockchain_data/' },
74+
{ text: 'Key Management', link: '/key_management' },
75+
{ text: 'Fee Estimation', link: '/fee_estimation' },
76+
{ text: 'Probing and Path Finding', link: '/probing' },
77+
],
78+
},
79+
{ text: 'Examples', link: '/examples' },
80+
],
81+
},
82+
{
83+
text: 'API Reference',
84+
collapsed: false,
85+
items: [
86+
{
87+
text: 'Rust',
88+
collapsed: true,
89+
items: [
90+
{ text: 'lightning', link: 'https://docs.rs/lightning/*/lightning/' },
91+
{ text: 'lightning-background-processor', link: 'https://docs.rs/lightning-background-processor/*/lightning_background_processor/' },
92+
{ text: 'lightning-block-sync', link: 'https://docs.rs/lightning-block-sync/*/lightning_block_sync/' },
93+
{ text: 'lightning-invoice', link: 'https://docs.rs/lightning-invoice/*/lightning_invoice/' },
94+
{ text: 'lightning-net-tokio', link: 'https://docs.rs/lightning-net-tokio/*/lightning_net_tokio/' },
95+
{ text: 'lightning-persister', link: 'https://docs.rs/lightning-persister/*/lightning_persister/' },
96+
{ text: 'lightning-rapid-gossip-sync', link: 'https://docs.rs/lightning-rapid-gossip-sync/*/lightning_rapid_gossip_sync/' },
97+
{ text: 'lightning-transaction-sync', link: 'https://docs.rs/lightning-transaction-sync/*/lightning_transaction_sync/' },
98+
{ text: 'lightning-custom-message', link: 'https://docs.rs/lightning-custom-message/*/lightning_custom_message/' },
99+
],
100+
},
101+
],
102+
},
103+
]
104+
105+
export default defineConfig({
106+
title: 'Lightning Dev Kit Documentation',
107+
description: 'LDK is a flexible lightning implementation with supporting batteries (or modules).',
108+
109+
cleanUrls: true,
110+
lastUpdated: true,
111+
112+
srcExclude: [
113+
'brainstorms/**',
114+
'plans/**',
115+
'todos/**',
116+
'README.md',
117+
],
118+
119+
ignoreDeadLinks: true,
120+
121+
head: [
122+
['link', { rel: 'icon', href: '/favicon.ico' }],
123+
['link', { rel: 'apple-touch-icon', href: '/img/favicon/apple-touch-icon.png' }],
124+
['link', { rel: 'manifest', href: '/site.webmanifest' }],
125+
['link', { rel: 'preload', as: 'font', type: 'font/woff2', crossorigin: '', href: '/fonts/ibm-plex-mono-400.woff2' }],
126+
['meta', { name: 'msapplication-config', content: '/browserconfig.xml' }],
127+
['meta', { name: 'theme-color', content: '#ffffff' }],
128+
['meta', { property: 'og:type', content: 'website' }],
129+
['meta', { property: 'og:url', content: 'https://lightningdevkit.org/' }],
130+
['meta', { property: 'og:image', content: 'https://lightningdevkit.org/card.png' }],
131+
['meta', { name: 'twitter:card', content: 'summary_large_image' }],
132+
['meta', { name: 'twitter:image', content: 'https://lightningdevkit.org/card.png' }],
133+
],
134+
135+
markdown: {
136+
lineNumbers: false,
137+
// Code blocks use a dark navy background in BOTH light and dark mode
138+
// (--vp-code-block-bg is dark in :root and .dark alike), so both Shiki
139+
// themes must be dark-on-navy. github-light/github-dark have muted tokens
140+
// that disappear on the navy; one-dark-pro stays high-contrast and legible.
141+
theme: {
142+
light: 'one-dark-pro',
143+
dark: 'one-dark-pro',
144+
},
145+
},
146+
147+
themeConfig: {
148+
// Hide the right-hand "On this page" outline on docs pages —
149+
// not part of the LDK design. Can still be enabled per-page via
150+
// frontmatter `outline: 'deep'` if a long page benefits from it.
151+
outline: false,
152+
153+
// Remove the "Previous/Next page" pager at the bottom of docs pages.
154+
docFooter: {
155+
prev: false,
156+
next: false,
157+
},
158+
159+
// Logo and wordmark are rendered together via `NavLogo.vue` in the
160+
// `nav-bar-title-before` slot, which uses the original sprite at
161+
// `/img/logo.svg` (with `#small` / `#large` symbols, each a
162+
// composed bolt + wordmark). No `themeConfig.logo` needed; setting
163+
// siteTitle to false hides the default plain-text title.
164+
siteTitle: false,
165+
166+
editLink: {
167+
pattern: 'https://github.com/lightningdevkit/lightningdevkit.org/edit/main/docs/:path',
168+
text: 'Edit this page on GitHub',
169+
},
170+
171+
nav: [
172+
{ text: 'Docs', link: '/introduction/' },
173+
{ text: 'Case Studies', link: '/case-studies' },
174+
{ text: 'Blog', link: '/blog/' },
175+
{ text: 'Discord', link: discordUrl },
176+
{ text: 'GitHub', link: githubUrl },
177+
],
178+
179+
sidebar: {
180+
'/blog/': blogSidebar,
181+
'/': docsSidebar,
182+
},
183+
184+
// Search: VitePress's built-in local search (MiniSearch-powered)
185+
// ships immediately and runs entirely client-side. Plan is to swap
186+
// to DocSearch v3 once Algolia approves the application — the
187+
// legacy v2 index (appId `BH4D9OD16A`, indexName `lightningdevkit`)
188+
// is deprecated and not compatible with VitePress's search config
189+
// shape. Apply at https://docsearch.algolia.com/apply (free for
190+
// OSS docs sites; 1–2 week approval typical).
191+
//
192+
// To swap to v3 once credentials arrive, replace the block below
193+
// with:
194+
//
195+
// search: {
196+
// provider: 'algolia',
197+
// options: {
198+
// appId: '<new v3 appId>',
199+
// apiKey: '<new public search-only key>',
200+
// indexName: 'lightningdevkit',
201+
// },
202+
// },
203+
search: {
204+
provider: 'local',
205+
},
206+
// No `footer` here: VitePress's default VPFooter would render its own
207+
// copyright above our custom SiteFooter (layout-bottom slot). The
208+
// SiteFooter carries the single copyright line.
209+
},
210+
211+
vite: {
212+
resolve: {
213+
// Alias bare `vue` and subpaths to VitePress's nested Vue 3.
214+
// Point at the PACKAGE DIRECTORY (not a specific file) so esbuild's
215+
// prebundler can package-resolve via vue's own package.json
216+
// exports map — pointing at index.mjs directly let the prebundler
217+
// cache Vue 2 from top-level node_modules.
218+
alias: [
219+
{ find: /^vue$/, replacement: vitepressVueDir },
220+
{ find: /^vue\/(.*)$/, replacement: path.join(vitepressVueDir, '$1') },
221+
],
222+
dedupe: ['vue'],
223+
},
224+
},
225+
})
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
<script setup lang="ts">
2+
import { computed } from 'vue'
3+
import { useData, useRoute, withBase } from 'vitepress'
4+
import { slugify } from '../../../blog/_taxonomy.ts'
5+
6+
const { frontmatter } = useData()
7+
const route = useRoute()
8+
9+
// Only individual blog articles get a header: they live under /blog/ and
10+
// carry a `date` in frontmatter (the blog index, tag, and author listing
11+
// pages have a title but no date).
12+
const isPost = computed(
13+
() => route.path.startsWith('/blog/') && !!frontmatter.value.date
14+
)
15+
16+
const authors = computed<string[]>(() => {
17+
const a = frontmatter.value.authors
18+
if (Array.isArray(a)) return a
19+
if (typeof a === 'string') return [a]
20+
return []
21+
})
22+
23+
function formatDate(iso: string): string {
24+
if (!iso) return ''
25+
const d = new Date(iso)
26+
return d.toLocaleDateString('en-US', {
27+
year: 'numeric',
28+
month: 'short',
29+
day: 'numeric',
30+
})
31+
}
32+
</script>
33+
34+
<template>
35+
<header v-if="isPost" class="blog-post-header">
36+
<h1 class="blog-post-header-title">{{ frontmatter.title }}</h1>
37+
<div class="blog-post-header-meta">
38+
<time v-if="frontmatter.date" :datetime="frontmatter.date">{{
39+
formatDate(frontmatter.date)
40+
}}</time>
41+
<span v-if="authors.length" class="blog-post-header-authors">
42+
by
43+
<template v-for="(author, idx) in authors" :key="author">
44+
<a :href="withBase(`/blog/author/${slugify(author)}/`)">{{
45+
author
46+
}}</a>
47+
<span v-if="idx < authors.length - 1">, </span>
48+
</template>
49+
</span>
50+
</div>
51+
</header>
52+
</template>
53+
54+
<style scoped>
55+
.blog-post-header {
56+
margin-bottom: 32px;
57+
}
58+
59+
.blog-post-header-title {
60+
margin: 0 0 12px;
61+
padding: 0;
62+
border: 0;
63+
font-size: 36px;
64+
font-weight: 700;
65+
line-height: 1.2;
66+
letter-spacing: -0.02em;
67+
color: var(--vp-c-text-1);
68+
}
69+
70+
.blog-post-header-meta {
71+
font-size: 15px;
72+
color: var(--vp-c-text-2);
73+
}
74+
75+
.blog-post-header-authors a {
76+
color: var(--vp-c-text-2);
77+
text-decoration: none;
78+
font-weight: 500;
79+
}
80+
81+
.blog-post-header-authors a:hover {
82+
color: var(--vp-c-brand-1);
83+
}
84+
</style>

0 commit comments

Comments
 (0)