blume 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/index.js +747 -471
- package/dist/cli/index.js.map +45 -38
- package/dist/types/core/schema.d.ts +289 -278
- package/dist/types/migrate/mintlify/assets.d.ts +8 -0
- package/docs/01-quickstart.mdx +5 -16
- package/docs/02-deployment.mdx +21 -54
- package/docs/advanced/api-reference.mdx +10 -37
- package/docs/advanced/blog.mdx +9 -25
- package/docs/advanced/changelog.mdx +10 -33
- package/docs/advanced/custom-pages.mdx +21 -78
- package/docs/configuration/ai.mdx +42 -103
- package/docs/configuration/analytics.mdx +20 -38
- package/docs/configuration/customization.mdx +40 -73
- package/docs/configuration/export.mdx +9 -34
- package/docs/configuration/index.mdx +67 -87
- package/docs/configuration/search.mdx +17 -54
- package/docs/configuration/seo.mdx +17 -48
- package/docs/configuration/theming.mdx +20 -42
- package/docs/content/components.mdx +42 -101
- package/docs/content/i18n.mdx +21 -72
- package/docs/content/index.mdx +18 -48
- package/docs/content/islands.mdx +25 -52
- package/docs/content/meta.mdx +23 -50
- package/docs/content/navigation.mdx +23 -62
- package/docs/content/sources.mdx +20 -83
- package/docs/content/syntax.mdx +37 -105
- package/docs/index.mdx +11 -40
- package/docs/reference/cli.mdx +18 -29
- package/docs/reference/frontmatter.mdx +2 -5
- package/package.json +1 -1
- package/src/astro/integration.ts +26 -3
- package/src/astro/islands.ts +6 -2
- package/src/astro/markdown-negotiation.ts +17 -3
- package/src/astro/pages.ts +6 -1
- package/src/astro/static-assets.ts +117 -0
- package/src/astro/templates.ts +48 -26
- package/src/cli/args.ts +23 -0
- package/src/cli/commands/build.ts +23 -0
- package/src/cli/commands/dev.ts +11 -2
- package/src/cli/commands/doctor.ts +10 -1
- package/src/cli/commands/eject.ts +3 -1
- package/src/cli/commands/init.ts +21 -1
- package/src/cli/commands/preview.ts +2 -1
- package/src/cli/commands/validate.ts +12 -1
- package/src/cli/dev-lock.ts +84 -0
- package/src/cli/log.ts +11 -0
- package/src/components/BlumePage.astro +2 -0
- package/src/components/content/YouTube.astro +35 -0
- package/src/components/content/youtube.ts +46 -0
- package/src/components/islands/ask-ai.tsx +14 -14
- package/src/components/props.ts +3 -0
- package/src/core/assets.ts +31 -0
- package/src/core/bridge.ts +10 -0
- package/src/core/builtin-tags.ts +1 -0
- package/src/core/diagnostics.ts +6 -1
- package/src/core/gitignore.ts +30 -0
- package/src/core/links.ts +60 -19
- package/src/core/schema.ts +7 -0
- package/src/core/sources/mdx-remote.ts +54 -8
- package/src/core/sources/normalize.ts +6 -1
- package/src/core/sources/notion.ts +49 -5
- package/src/core/sources/sanity.ts +5 -1
- package/src/deploy/rss.ts +1 -8
- package/src/deploy/sitemap.ts +20 -1
- package/src/deploy/xml.ts +8 -0
- package/src/markdown/directives.ts +15 -7
- package/src/markdown/package-commands.ts +26 -4
- package/src/migrate/fumadocs/content.ts +14 -1
- package/src/migrate/fumadocs/groups.ts +7 -0
- package/src/migrate/fumadocs/index.ts +5 -2
- package/src/migrate/mintlify/assets.ts +46 -0
- package/src/migrate/mintlify/index.ts +53 -45
- package/src/migrate/shared.ts +12 -27
- package/src/og/card.ts +14 -2
- package/src/registry/eject.ts +13 -3
- package/src/registry/registry.ts +6 -0
- package/src/registry/rewrite-imports.ts +31 -19
- package/src/search/documents.ts +23 -5
- package/src/search/sync/algolia.ts +5 -1
- package/src/search/sync/typesense.ts +24 -16
- package/src/theme/palette.ts +26 -7
package/docs/content/syntax.mdx
CHANGED
|
@@ -3,19 +3,11 @@ title: Syntax
|
|
|
3
3
|
description: Every Markdown and MDX feature Blume renders — formatting, lists, tables, callouts, code blocks, package installs, and math.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
Blume renders standard Markdown and MDX with a curated, GitHub-flavored feature
|
|
7
|
-
set — no imports, no configuration. Write content the way you already do; this
|
|
8
|
-
page shows everything that's supported, with a live preview and the source for
|
|
9
|
-
each.
|
|
6
|
+
Blume renders standard Markdown and MDX with a curated, GitHub-flavored feature set — no imports, no configuration. Write content the way you already do; this page shows everything that's supported, with a live preview and the source for each.
|
|
10
7
|
|
|
11
8
|
## Headings
|
|
12
9
|
|
|
13
|
-
Structure a page with headings. Blume renders your frontmatter `title` as the
|
|
14
|
-
page heading, so start your content at `##` — `##` and `###` become entries
|
|
15
|
-
in the table of contents. Every `##`–`######` heading is also wrapped in a link
|
|
16
|
-
to its own anchor, so readers can click a heading to copy, bookmark, or share a
|
|
17
|
-
permalink straight to that section (hover to reveal the `#`). Turn this off with
|
|
18
|
-
`markdown: { headingAnchors: false }` in `blume.config.ts`.
|
|
10
|
+
Structure a page with headings. Blume renders your frontmatter `title` as the page heading, so start your content at `##` — `##` and `###` become entries in the table of contents. Every `##`–`######` heading is also wrapped in a link to its own anchor, so readers can click a heading to copy, bookmark, or share a permalink straight to that section (hover to reveal the `#`). Turn this off with `markdown: { headingAnchors: false }` in `blume.config.ts`.
|
|
19
11
|
|
|
20
12
|
```md
|
|
21
13
|
## Section
|
|
@@ -27,8 +19,7 @@ permalink straight to that section (hover to reveal the `#`). Turn this off with
|
|
|
27
19
|
|
|
28
20
|
## Emphasis
|
|
29
21
|
|
|
30
|
-
Inline formatting for stressing words, marking deletions, and showing code or
|
|
31
|
-
keystrokes mid-sentence.
|
|
22
|
+
Inline formatting for stressing words, marking deletions, and showing code or keystrokes mid-sentence.
|
|
32
23
|
|
|
33
24
|
**Bold**, _italic_, ~~strikethrough~~, and `inline code`.
|
|
34
25
|
|
|
@@ -48,8 +39,7 @@ E = mc^2^ and H~2~O.
|
|
|
48
39
|
|
|
49
40
|
## Blockquotes
|
|
50
41
|
|
|
51
|
-
Set off a quotation, callout aside, or an editorial note from the surrounding
|
|
52
|
-
text.
|
|
42
|
+
Set off a quotation, callout aside, or an editorial note from the surrounding text.
|
|
53
43
|
|
|
54
44
|
> Documentation that's fast, AI-ready, and zero-config — down to the template.
|
|
55
45
|
|
|
@@ -59,8 +49,7 @@ text.
|
|
|
59
49
|
|
|
60
50
|
## Lists
|
|
61
51
|
|
|
62
|
-
Use unordered lists for unordered sets, ordered lists for sequences, and task
|
|
63
|
-
lists for checklists and roadmaps.
|
|
52
|
+
Use unordered lists for unordered sets, ordered lists for sequences, and task lists for checklists and roadmaps.
|
|
64
53
|
|
|
65
54
|
- Markdown-first authoring
|
|
66
55
|
- Static by default
|
|
@@ -90,8 +79,7 @@ lists for checklists and roadmaps.
|
|
|
90
79
|
|
|
91
80
|
## Tables
|
|
92
81
|
|
|
93
|
-
Tabulate structured data — config options, comparison matrices, parameter lists.
|
|
94
|
-
Use colons in the divider row to align columns.
|
|
82
|
+
Tabulate structured data — config options, comparison matrices, parameter lists. Use colons in the divider row to align columns.
|
|
95
83
|
|
|
96
84
|
| Command | Description | Output |
|
|
97
85
|
| ------------- | --------------------- | :-----: |
|
|
@@ -107,8 +95,7 @@ Use colons in the divider row to align columns.
|
|
|
107
95
|
|
|
108
96
|
## Links and images
|
|
109
97
|
|
|
110
|
-
Link to other pages or external sites. Images accept any path under `public/` or
|
|
111
|
-
a remote URL.
|
|
98
|
+
Link to other pages or external sites. Images accept any path under `public/` (or another directory listed in [`content.assets`](/docs/configuration#content)) or a remote URL.
|
|
112
99
|
|
|
113
100
|
Read the [quickstart](/docs/quickstart) to get started.
|
|
114
101
|
|
|
@@ -118,9 +105,7 @@ Read the [quickstart](/docs/quickstart) to get started.
|
|
|
118
105
|

|
|
119
106
|
```
|
|
120
107
|
|
|
121
|
-
Content images are click-to-zoom by default — readers can click any image to open
|
|
122
|
-
it in a lightbox. Turn this off with `markdown: { imageZoom: false }` in
|
|
123
|
-
`blume.config.ts`, or opt a single image out with `data-no-zoom`.
|
|
108
|
+
Content images are click-to-zoom by default — readers can click any image to open it in a lightbox. Turn this off with `markdown: { imageZoom: false }` in `blume.config.ts`, or opt a single image out with `data-no-zoom`.
|
|
124
109
|
|
|
125
110
|
## Horizontal rule
|
|
126
111
|
|
|
@@ -134,10 +119,7 @@ Separate major shifts in topic within a long page.
|
|
|
134
119
|
|
|
135
120
|
## Code blocks
|
|
136
121
|
|
|
137
|
-
Fenced code blocks are syntax-highlighted with a header showing the language —
|
|
138
|
-
with a brand icon for recognized languages — and a copy button. Add a **title**
|
|
139
|
-
after the language — typically a filename — and it replaces the language label in
|
|
140
|
-
the header.
|
|
122
|
+
Fenced code blocks are syntax-highlighted with a header showing the language — with a brand icon for recognized languages — and a copy button. Add a **title** after the language — typically a filename — and it replaces the language label in the header.
|
|
141
123
|
|
|
142
124
|
```ts blume.config.ts
|
|
143
125
|
import { defineConfig } from "blume";
|
|
@@ -157,14 +139,11 @@ export default defineConfig({
|
|
|
157
139
|
```
|
|
158
140
|
````
|
|
159
141
|
|
|
160
|
-
Inline code can be highlighted too: add a `{:lang}` marker inside a backtick span
|
|
161
|
-
and it's colored like a tiny code block — `useState(){:js}` or
|
|
162
|
-
`T extends object{:ts}`. Turn it on with `markdown: { code: { inline: true } }`.
|
|
142
|
+
Inline code can be highlighted too: add a `{:lang}` marker inside a backtick span and it's colored like a tiny code block — `useState(){:js}` or `T extends object{:ts}`. Turn it on with `markdown: { code: { inline: true } }`.
|
|
163
143
|
|
|
164
144
|
### Line numbers
|
|
165
145
|
|
|
166
|
-
Append `lineNumbers` to render a line-number gutter — on its own or alongside a
|
|
167
|
-
title:
|
|
146
|
+
Append `lineNumbers` to render a line-number gutter — on its own or alongside a title:
|
|
168
147
|
|
|
169
148
|
```ts server.ts lineNumbers
|
|
170
149
|
import { serve } from "blume";
|
|
@@ -182,9 +161,7 @@ serve({ port: 3000 });
|
|
|
182
161
|
|
|
183
162
|
### Highlighting
|
|
184
163
|
|
|
185
|
-
Annotate code with GitHub-style comments to draw attention to lines, words, and
|
|
186
|
-
changes. The comments are stripped from the rendered output, so the code stays
|
|
187
|
-
copy-paste clean. All four are on by default — no configuration.
|
|
164
|
+
Annotate code with GitHub-style comments to draw attention to lines, words, and changes. The comments are stripped from the rendered output, so the code stays copy-paste clean. All four are on by default — no configuration.
|
|
188
165
|
|
|
189
166
|
Mark a line with `// [!code highlight]` to give it a highlighted background:
|
|
190
167
|
|
|
@@ -194,8 +171,7 @@ const config = defineConfig({
|
|
|
194
171
|
});
|
|
195
172
|
```
|
|
196
173
|
|
|
197
|
-
Show changes with `// [!code ++]` for additions and `// [!code --]` for
|
|
198
|
-
removals, rendered as a green/red diff:
|
|
174
|
+
Show changes with `// [!code ++]` for additions and `// [!code --]` for removals, rendered as a green/red diff:
|
|
199
175
|
|
|
200
176
|
```ts
|
|
201
177
|
export default defineConfig({
|
|
@@ -212,8 +188,7 @@ import { serve } from "blume"; // [!code word:serve]
|
|
|
212
188
|
serve({ port: 3000 });
|
|
213
189
|
```
|
|
214
190
|
|
|
215
|
-
Dim everything except the lines you mark with `// [!code focus]` (the rest
|
|
216
|
-
sharpens on hover):
|
|
191
|
+
Dim everything except the lines you mark with `// [!code focus]` (the rest sharpens on hover):
|
|
217
192
|
|
|
218
193
|
```ts
|
|
219
194
|
export default defineConfig({
|
|
@@ -222,9 +197,7 @@ export default defineConfig({
|
|
|
222
197
|
});
|
|
223
198
|
```
|
|
224
199
|
|
|
225
|
-
Or highlight lines by **number** instead of comments — useful when you can't edit
|
|
226
|
-
the code. Put a brace range after the language; single lines, comma lists, and
|
|
227
|
-
`start-end` spans all work:
|
|
200
|
+
Or highlight lines by **number** instead of comments — useful when you can't edit the code. Put a brace range after the language; single lines, comma lists, and `start-end` spans all work:
|
|
228
201
|
|
|
229
202
|
```ts {1,4-5}
|
|
230
203
|
import { defineConfig } from "blume";
|
|
@@ -248,10 +221,7 @@ export default defineConfig({
|
|
|
248
221
|
|
|
249
222
|
### Display types
|
|
250
223
|
|
|
251
|
-
Mark a TypeScript block `twoslash` to display real types straight from the
|
|
252
|
-
compiler — powered by [Twoslash](https://shiki.style/packages/twoslash). Hover
|
|
253
|
-
any token to see its inferred type, and add an inline `^?` query to pin a type
|
|
254
|
-
below the line.
|
|
224
|
+
Mark a TypeScript block `twoslash` to display real types straight from the compiler — powered by [Twoslash](https://shiki.style/packages/twoslash). Hover any token to see its inferred type, and add an inline `^?` query to pin a type below the line.
|
|
255
225
|
|
|
256
226
|
```ts twoslash
|
|
257
227
|
const config = {
|
|
@@ -272,15 +242,11 @@ config.title;
|
|
|
272
242
|
```
|
|
273
243
|
````
|
|
274
244
|
|
|
275
|
-
:::note
|
|
276
|
-
Hide the language icons or wrap long lines instead of scrolling with
|
|
277
|
-
`markdown: { code: { icons: false, wrap: true } }` in `blume.config.ts`.
|
|
278
|
-
:::
|
|
245
|
+
:::note Hide the language icons or wrap long lines instead of scrolling with `markdown: { code: { icons: false, wrap: true } }` in `blume.config.ts`. :::
|
|
279
246
|
|
|
280
247
|
## Package install
|
|
281
248
|
|
|
282
|
-
A `package-install` block turns a single install command into a tabbed snippet
|
|
283
|
-
for npm, pnpm, yarn, and bun — so readers copy the one that matches their setup.
|
|
249
|
+
A `package-install` block turns a single install command into a tabbed snippet for npm, pnpm, yarn, and bun — so readers copy the one that matches their setup.
|
|
284
250
|
|
|
285
251
|
```package-install
|
|
286
252
|
npm i blume
|
|
@@ -294,9 +260,7 @@ npm i blume
|
|
|
294
260
|
|
|
295
261
|
## Diagrams
|
|
296
262
|
|
|
297
|
-
A `mermaid` block renders a [Mermaid](https://mermaid.js.org) diagram — flowcharts,
|
|
298
|
-
sequence diagrams, and more — straight from text. Diagrams follow the active color
|
|
299
|
-
theme and re-render when it changes.
|
|
263
|
+
A `mermaid` block renders a [Mermaid](https://mermaid.js.org) diagram — flowcharts, sequence diagrams, and more — straight from text. Diagrams follow the active color theme and re-render when it changes.
|
|
300
264
|
|
|
301
265
|
```mermaid
|
|
302
266
|
flowchart LR
|
|
@@ -314,105 +278,77 @@ flowchart LR
|
|
|
314
278
|
```
|
|
315
279
|
````
|
|
316
280
|
|
|
317
|
-
Diagrams render on the client, so this is an MDX-only feature, and the Mermaid
|
|
318
|
-
library loads only on pages that include one.
|
|
281
|
+
Diagrams render on the client, so this is an MDX-only feature, and the Mermaid library loads only on pages that include one.
|
|
319
282
|
|
|
320
283
|
## Callouts
|
|
321
284
|
|
|
322
|
-
Callouts pull a reader's attention to context, advice, or risk. Write them as
|
|
323
|
-
`:::type` directives; add a title in brackets, like `:::warning[Heads up]`.
|
|
285
|
+
Callouts pull a reader's attention to context, advice, or risk. Write them as `:::type` directives; add a title in brackets, like `:::warning[Heads up]`.
|
|
324
286
|
|
|
325
287
|
### Note
|
|
326
288
|
|
|
327
289
|
Neutral, supporting context the reader should keep in mind.
|
|
328
290
|
|
|
329
|
-
:::note
|
|
330
|
-
Blume regenerates `.blume/` on every run — never edit it by hand.
|
|
331
|
-
:::
|
|
291
|
+
:::note Blume regenerates `.blume/` on every run — never edit it by hand. :::
|
|
332
292
|
|
|
333
293
|
```md
|
|
334
|
-
:::note
|
|
335
|
-
Blume regenerates `.blume/` on every run — never edit it by hand.
|
|
336
|
-
:::
|
|
294
|
+
:::note Blume regenerates `.blume/` on every run — never edit it by hand. :::
|
|
337
295
|
```
|
|
338
296
|
|
|
339
297
|
### Tip
|
|
340
298
|
|
|
341
299
|
A helpful shortcut or best practice that isn't required but makes life easier.
|
|
342
300
|
|
|
343
|
-
:::tip
|
|
344
|
-
Set `deployment.site` so sitemaps and Open Graph images use absolute URLs.
|
|
345
|
-
:::
|
|
301
|
+
:::tip Set `deployment.site` so sitemaps and Open Graph images use absolute URLs. :::
|
|
346
302
|
|
|
347
303
|
```md
|
|
348
|
-
:::tip
|
|
349
|
-
Set `deployment.site` so sitemaps and Open Graph images use absolute URLs.
|
|
350
|
-
:::
|
|
304
|
+
:::tip Set `deployment.site` so sitemaps and Open Graph images use absolute URLs. :::
|
|
351
305
|
```
|
|
352
306
|
|
|
353
307
|
### Success
|
|
354
308
|
|
|
355
309
|
Confirm a positive outcome or that a step completed as expected.
|
|
356
310
|
|
|
357
|
-
:::success
|
|
358
|
-
Your docs built successfully and are ready to deploy.
|
|
359
|
-
:::
|
|
311
|
+
:::success Your docs built successfully and are ready to deploy. :::
|
|
360
312
|
|
|
361
313
|
```md
|
|
362
|
-
:::success
|
|
363
|
-
Your docs built successfully and are ready to deploy.
|
|
364
|
-
:::
|
|
314
|
+
:::success Your docs built successfully and are ready to deploy. :::
|
|
365
315
|
```
|
|
366
316
|
|
|
367
317
|
### Warning
|
|
368
318
|
|
|
369
319
|
Flag something that needs care to avoid a mistake or surprising behavior.
|
|
370
320
|
|
|
371
|
-
:::warning[Heads up]
|
|
372
|
-
Switching to `output: "server"` requires an adapter before you can deploy.
|
|
373
|
-
:::
|
|
321
|
+
:::warning[Heads up] Switching to `output: "server"` requires an adapter before you can deploy. :::
|
|
374
322
|
|
|
375
323
|
```md
|
|
376
|
-
:::warning[Heads up]
|
|
377
|
-
Switching to `output: "server"` requires an adapter before you can deploy.
|
|
378
|
-
:::
|
|
324
|
+
:::warning[Heads up] Switching to `output: "server"` requires an adapter before you can deploy. :::
|
|
379
325
|
```
|
|
380
326
|
|
|
381
327
|
### Danger
|
|
382
328
|
|
|
383
329
|
Call out a destructive or breaking action that can't easily be undone.
|
|
384
330
|
|
|
385
|
-
:::danger
|
|
386
|
-
`blume eject` is a one-way step — the generated Astro project becomes yours.
|
|
387
|
-
:::
|
|
331
|
+
:::danger `blume eject` is a one-way step — the generated Astro project becomes yours. :::
|
|
388
332
|
|
|
389
333
|
```md
|
|
390
|
-
:::danger
|
|
391
|
-
`blume eject` is a one-way step — the generated Astro project becomes yours.
|
|
392
|
-
:::
|
|
334
|
+
:::danger `blume eject` is a one-way step — the generated Astro project becomes yours. :::
|
|
393
335
|
```
|
|
394
336
|
|
|
395
337
|
### Info
|
|
396
338
|
|
|
397
339
|
An informational aside; an alias-friendly default that reads as neutral.
|
|
398
340
|
|
|
399
|
-
:::info
|
|
400
|
-
The core theme ships zero client JavaScript.
|
|
401
|
-
:::
|
|
341
|
+
:::info The core theme ships zero client JavaScript. :::
|
|
402
342
|
|
|
403
343
|
```md
|
|
404
|
-
:::info
|
|
405
|
-
The core theme ships zero client JavaScript.
|
|
406
|
-
:::
|
|
344
|
+
:::info The core theme ships zero client JavaScript. :::
|
|
407
345
|
```
|
|
408
346
|
|
|
409
|
-
The names `caution`, `error`, `important`, and `warn` are accepted as aliases for
|
|
410
|
-
`warning`, `danger`, `note`, and `warning` respectively.
|
|
347
|
+
The names `caution`, `error`, `important`, and `warn` are accepted as aliases for `warning`, `danger`, `note`, and `warning` respectively.
|
|
411
348
|
|
|
412
349
|
## Math
|
|
413
350
|
|
|
414
|
-
Render LaTeX with KaTeX for formulas in prose or as centered blocks — useful for
|
|
415
|
-
math-heavy or scientific docs. Inline math goes in `$…$`; block math in `$$…$$`.
|
|
351
|
+
Render LaTeX with KaTeX for formulas in prose or as centered blocks — useful for math-heavy or scientific docs. Inline math goes in `$…$`; block math in `$$…$$`.
|
|
416
352
|
|
|
417
353
|
The Pythagorean theorem is $a^2 + b^2 = c^2$.
|
|
418
354
|
|
|
@@ -428,15 +364,11 @@ $$
|
|
|
428
364
|
$$
|
|
429
365
|
```
|
|
430
366
|
|
|
431
|
-
:::note
|
|
432
|
-
Math is opt-in because `$` is common in prose and code. Enable it with
|
|
433
|
-
`markdown: { math: true }` in `blume.config.ts`.
|
|
434
|
-
:::
|
|
367
|
+
:::note Math is opt-in because `$` is common in prose and code. Enable it with `markdown: { math: true }` in `blume.config.ts`. :::
|
|
435
368
|
|
|
436
369
|
## Smart punctuation
|
|
437
370
|
|
|
438
|
-
Blume converts straight quotes and dashes to typographic equivalents as you
|
|
439
|
-
write, so prose reads like it was typeset — no special characters required.
|
|
371
|
+
Blume converts straight quotes and dashes to typographic equivalents as you write, so prose reads like it was typeset — no special characters required.
|
|
440
372
|
|
|
441
373
|
"Quotes" become curly, -- becomes an en dash, --- an em dash, and ... an ellipsis.
|
|
442
374
|
|
package/docs/index.mdx
CHANGED
|
@@ -6,9 +6,7 @@ sidebar:
|
|
|
6
6
|
order: 0
|
|
7
7
|
---
|
|
8
8
|
|
|
9
|
-
Drop Markdown or MDX into a folder, run `blume dev`, and get a production-grade
|
|
10
|
-
docs site — navigation, search, theming, Open Graph images, and a rich component
|
|
11
|
-
library — with no app boilerplate to write or maintain.
|
|
9
|
+
Drop Markdown or MDX into a folder, run `blume dev`, and get a production-grade docs site — navigation, search, theming, Open Graph images, and a rich component library — with no app boilerplate to write or maintain.
|
|
12
10
|
|
|
13
11
|
<CardGroup cols={2}>
|
|
14
12
|
<Card title="Quickstart" href="/docs/quickstart" icon="rocket">
|
|
@@ -29,61 +27,34 @@ Blume takes the best of both worlds. The framework is the template, so the only
|
|
|
29
27
|
|
|
30
28
|
### Fast by default
|
|
31
29
|
|
|
32
|
-
Blume builds on Astro and Vite and renders static HTML by default — fast,
|
|
33
|
-
cacheable, and cheap to host. The core theme is React-free and ships **zero
|
|
34
|
-
client JavaScript**, so pages score well on Core Web Vitals out of the box. Dev
|
|
35
|
-
startup and hot reload feel Vite-native, and you opt into server features only
|
|
36
|
-
when you need them.
|
|
30
|
+
Blume builds on Astro and Vite and renders static HTML by default — fast, cacheable, and cheap to host. The core theme is React-free and ships **zero client JavaScript**, so pages score well on Core Web Vitals out of the box. Dev startup and hot reload feel Vite-native, and you opt into server features only when you need them.
|
|
37
31
|
|
|
38
32
|
### AI-ready out of the box
|
|
39
33
|
|
|
40
|
-
Every Blume site speaks fluent machine. It emits [`llms.txt` and
|
|
41
|
-
`llms-full.txt`](/docs/configuration/ai), serves any page's raw Markdown by
|
|
42
|
-
appending `.md` to its URL, and gives readers **Copy as Markdown** and **Open in
|
|
43
|
-
chat** actions on every page. Add an optional in-page **Ask AI** assistant, or
|
|
44
|
-
host an [**MCP server**](/docs/configuration/ai#mcp-server) so coding agents like
|
|
45
|
-
Claude Code and Cursor can search and read your docs directly — no scraping, no
|
|
46
|
-
hosted service. Your Markdown is the source of truth for both humans and models.
|
|
34
|
+
Every Blume site speaks fluent machine. It emits [`llms.txt` and `llms-full.txt`](/docs/configuration/ai), serves any page's raw Markdown by appending `.md` to its URL, and gives readers **Copy as Markdown** and **Open in chat** actions on every page. Add an optional in-page **Ask AI** assistant, or host an [**MCP server**](/docs/configuration/ai#mcp-server) so coding agents like Claude Code and Cursor can search and read your docs directly — no scraping, no hosted service. Your Markdown is the source of truth for both humans and models.
|
|
47
35
|
|
|
48
36
|
### Zero configuration — even the template
|
|
49
37
|
|
|
50
|
-
A folder of docs is a complete project. There's no starter to clone, no Astro or
|
|
51
|
-
Tailwind to set up, and no template to maintain. Navigation is inferred from your
|
|
52
|
-
files, [search](/docs/configuration/search) works in dev and production without a hosted
|
|
53
|
-
service, and theming is a handful of tokens. Everything has a sensible default;
|
|
54
|
-
configuration is something you reach for, not something you start with.
|
|
38
|
+
A folder of docs is a complete project. There's no starter to clone, no Astro or Tailwind to set up, and no template to maintain. Navigation is inferred from your files, [search](/docs/configuration/search) works in dev and production without a hosted service, and theming is a handful of tokens. Everything has a sensible default; configuration is something you reach for, not something you start with.
|
|
55
39
|
|
|
56
40
|
### Type-safe to the core
|
|
57
41
|
|
|
58
|
-
Your [`blume.config.ts`](/docs/configuration) and every
|
|
59
|
-
[`meta.ts`](/docs/content/meta) are real TypeScript — validated by a schema and
|
|
60
|
-
authored with `defineConfig` and `defineMeta`. Your editor autocompletes every
|
|
61
|
-
option and catches typos, invalid values, and missing fields as you type, long
|
|
62
|
-
before a build. Configuration is code you can refactor, compute, and trust — not
|
|
63
|
-
loosely-typed YAML.
|
|
42
|
+
Your [`blume.config.ts`](/docs/configuration) and every [`meta.ts`](/docs/content/meta) are real TypeScript — validated by a schema and authored with `defineConfig` and `defineMeta`. Your editor autocompletes every option and catches typos, invalid values, and missing fields as you type, long before a build. Configuration is code you can refactor, compute, and trust — not loosely-typed YAML.
|
|
64
43
|
|
|
65
44
|
## Everything included
|
|
66
45
|
|
|
67
|
-
- **Components** — callouts, cards, steps, tabs, accordions, badges, file trees,
|
|
68
|
-
|
|
69
|
-
- **
|
|
70
|
-
for large sites. No hosted index.
|
|
71
|
-
- **AI** — [`llms.txt`, raw Markdown URLs, Copy as Markdown, Open in chat, an
|
|
72
|
-
Ask AI assistant, and a hosted MCP server](/docs/configuration/ai).
|
|
46
|
+
- **Components** — callouts, cards, steps, tabs, accordions, badges, file trees, and parameter tables, usable in MDX with [no imports](/docs/content/components).
|
|
47
|
+
- **Local search** — Orama works in dev and production; Pagefind is one flag away for large sites. No hosted index.
|
|
48
|
+
- **AI** — [`llms.txt`, raw Markdown URLs, Copy as Markdown, Open in chat, an Ask AI assistant, and a hosted MCP server](/docs/configuration/ai).
|
|
73
49
|
- **Navigation** — inferred from files, refined with `meta.ts` or config.
|
|
74
50
|
- **SEO** — metadata, Open Graph images, RSS feeds, and JSON-LD, [built in](/docs/configuration/seo).
|
|
75
|
-
- **Customization** — component overrides, React islands, custom pages, theme
|
|
76
|
-
tokens, and a source-component registry via `blume add`.
|
|
51
|
+
- **Customization** — component overrides, React islands, custom pages, theme tokens, and a source-component registry via `blume add`.
|
|
77
52
|
- **Migration** — `blume migrate mintlify | starlight | nextra | fumadocs`.
|
|
78
|
-
- **Eject** — `blume eject` produces a standalone Astro project that still uses
|
|
79
|
-
the `blume` package.
|
|
53
|
+
- **Eject** — `blume eject` produces a standalone Astro project that still uses the `blume` package.
|
|
80
54
|
|
|
81
55
|
## How it works
|
|
82
56
|
|
|
83
|
-
The Blume CLI discovers your content, builds a content graph, and generates a
|
|
84
|
-
hidden Astro project under `.blume/` that it drives for dev and build. The
|
|
85
|
-
generated runtime is an implementation detail — you write Markdown, Blume handles
|
|
86
|
-
the rest — until you choose to eject and own it.
|
|
57
|
+
The Blume CLI discovers your content, builds a content graph, and generates a hidden Astro project under `.blume/` that it drives for dev and build. The generated runtime is an implementation detail — you write Markdown, Blume handles the rest — until you choose to eject and own it.
|
|
87
58
|
|
|
88
59
|
## Next steps
|
|
89
60
|
|
package/docs/reference/cli.mdx
CHANGED
|
@@ -9,19 +9,19 @@ blume <command> [options]
|
|
|
9
9
|
|
|
10
10
|
## Commands
|
|
11
11
|
|
|
12
|
-
| Command
|
|
13
|
-
|
|
|
14
|
-
| `blume init`
|
|
15
|
-
| `blume dev`
|
|
16
|
-
| `blume build`
|
|
17
|
-
| `blume preview`
|
|
18
|
-
| `blume add <item>`
|
|
12
|
+
| Command | Description |
|
|
13
|
+
| --- | --- |
|
|
14
|
+
| `blume init` | Scaffold a minimal project. |
|
|
15
|
+
| `blume dev` | Start the dev server with hot reload. |
|
|
16
|
+
| `blume build` | Build the static (or server) site. |
|
|
17
|
+
| `blume preview` | Preview the last build. |
|
|
18
|
+
| `blume add <item>` | Install a source component from the registry. |
|
|
19
19
|
| `blume migrate <tool>` | Migrate from Mintlify, Starlight, Nextra, or Fumadocs. |
|
|
20
|
-
| `blume sync`
|
|
21
|
-
| `blume eject`
|
|
22
|
-
| `blume check`
|
|
23
|
-
| `blume doctor`
|
|
24
|
-
| `blume validate`
|
|
20
|
+
| `blume sync` | Re-fetch remote content sources and regenerate. |
|
|
21
|
+
| `blume eject` | Promote the runtime into a standalone Astro app. |
|
|
22
|
+
| `blume check` | Type-check the site with `astro check`. |
|
|
23
|
+
| `blume doctor` | Diagnose config and content problems. |
|
|
24
|
+
| `blume validate` | Validate links across your content. |
|
|
25
25
|
|
|
26
26
|
## Common flags
|
|
27
27
|
|
|
@@ -45,17 +45,11 @@ blume <command> [options]
|
|
|
45
45
|
- `blume eject --yes` — skip the confirmation prompt.
|
|
46
46
|
- `blume validate --external` — also check external links over the network.
|
|
47
47
|
- `blume validate --strict` — exit non-zero on warnings too.
|
|
48
|
-
- `blume validate --json` / `blume doctor --json` — emit diagnostics as JSON on
|
|
49
|
-
stdout (with `code`, `severity`, `file`, `line`/`column`, and `docsUrl`) for CI
|
|
50
|
-
and editor integrations.
|
|
48
|
+
- `blume validate --json` / `blume doctor --json` — emit diagnostics as JSON on stdout (with `code`, `severity`, `file`, `line`/`column`, and `docsUrl`) for CI and editor integrations.
|
|
51
49
|
|
|
52
50
|
## Type-checking
|
|
53
51
|
|
|
54
|
-
`blume check` runs [`astro check`](https://docs.astro.build/en/reference/cli-reference/#astro-check)
|
|
55
|
-
over your project. It regenerates the `.blume` runtime, syncs Astro's content
|
|
56
|
-
types, then reports any TypeScript errors — in your `blume.config.ts`, in custom
|
|
57
|
-
`.astro` pages, and in the components they import. It exits non-zero when there
|
|
58
|
-
are errors, so it works as a `typecheck` step in CI:
|
|
52
|
+
`blume check` runs [`astro check`](https://docs.astro.build/en/reference/cli-reference/#astro-check) over your project. It regenerates the `.blume` runtime, syncs Astro's content types, then reports any TypeScript errors — in your `blume.config.ts`, in custom `.astro` pages, and in the components they import. It exits non-zero when there are errors, so it works as a `typecheck` step in CI:
|
|
59
53
|
|
|
60
54
|
```json title="package.json"
|
|
61
55
|
{
|
|
@@ -65,8 +59,7 @@ are errors, so it works as a `typecheck` step in CI:
|
|
|
65
59
|
}
|
|
66
60
|
```
|
|
67
61
|
|
|
68
|
-
Add a `tsconfig.json` extending Astro's config to your project root so authored
|
|
69
|
-
pages resolve `blume/*` imports and virtual modules like `blume:data`:
|
|
62
|
+
Add a `tsconfig.json` extending Astro's config to your project root so authored pages resolve `blume/*` imports and virtual modules like `blume:data`:
|
|
70
63
|
|
|
71
64
|
```json title="tsconfig.json"
|
|
72
65
|
{
|
|
@@ -81,11 +74,7 @@ Without a project `tsconfig.json`, only the generated runtime is checked.
|
|
|
81
74
|
|
|
82
75
|
`blume validate` checks every link discovered in your content:
|
|
83
76
|
|
|
84
|
-
- **Internal page links** (`/guides/intro`, `./sibling`) must resolve to a real
|
|
85
|
-
|
|
86
|
-
- **Anchor links** (`#section`, `/guides/intro#setup`) must match a heading on
|
|
87
|
-
the target page — misses are warnings.
|
|
77
|
+
- **Internal page links** (`/guides/intro`, `./sibling`) must resolve to a real page — broken ones are reported as errors.
|
|
78
|
+
- **Anchor links** (`#section`, `/guides/intro#setup`) must match a heading on the target page — misses are warnings.
|
|
88
79
|
- **Asset links** (`/logo.png`) are checked against the `public/` directory.
|
|
89
|
-
- **External links** are only checked with `--external` (off by default since it
|
|
90
|
-
requires the network); dead links (404/410/unreachable) are errors, while
|
|
91
|
-
rate-limited or transient responses (403/429/5xx/timeout) are warnings.
|
|
80
|
+
- **External links** are only checked with `--external` (off by default since it requires the network); dead links (404/410/unreachable) are errors, while rate-limited or transient responses (403/429/5xx/timeout) are warnings.
|
|
@@ -64,8 +64,7 @@ search:
|
|
|
64
64
|
|
|
65
65
|
## Changelog
|
|
66
66
|
|
|
67
|
-
Changelog entries (`type: changelog`) accept an optional `changelog` object for
|
|
68
|
-
richer feed and display metadata:
|
|
67
|
+
Changelog entries (`type: changelog`) accept an optional `changelog` object for richer feed and display metadata:
|
|
69
68
|
|
|
70
69
|
```yaml lineNumbers
|
|
71
70
|
type: changelog
|
|
@@ -75,8 +74,6 @@ changelog:
|
|
|
75
74
|
category: Features
|
|
76
75
|
```
|
|
77
76
|
|
|
78
|
-
`date` may live here or at the top level — both feed the
|
|
79
|
-
[changelog RSS feed](/docs/content#feeds). See [Changelog](/docs/advanced/changelog) for the
|
|
80
|
-
generated timeline page and feed.
|
|
77
|
+
`date` may live here or at the top level — both feed the [changelog RSS feed](/docs/content#feeds). See [Changelog](/docs/advanced/changelog) for the generated timeline page and feed.
|
|
81
78
|
|
|
82
79
|
Schemas are exported from `blume/schema` for editor and migration tooling.
|
package/package.json
CHANGED
package/src/astro/integration.ts
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import type { IncomingMessage, ServerResponse } from "node:http";
|
|
2
|
+
import { fileURLToPath } from "node:url";
|
|
2
3
|
|
|
3
4
|
import type { AstroIntegration } from "astro";
|
|
4
5
|
|
|
6
|
+
import type { AssetMount } from "../core/assets.ts";
|
|
5
7
|
import { enrichDiagnostic } from "../core/diagnostics.ts";
|
|
6
8
|
import type { Diagnostic } from "../core/types.ts";
|
|
7
9
|
import { markdownVariantUrl, prefersMarkdown } from "./markdown-negotiation.ts";
|
|
10
|
+
import { copyAssetMounts, serveAssetMounts } from "./static-assets.ts";
|
|
8
11
|
|
|
9
12
|
/** The dev server's HMR channel — either `.ws` (Vite ≤5) or `.hot` (Vite 6+). */
|
|
10
13
|
interface OverlayChannel {
|
|
@@ -72,6 +75,13 @@ export interface BlumeIntegrationOptions {
|
|
|
72
75
|
pages: BlumePageRoute[];
|
|
73
76
|
/** Page routes that have a raw-Markdown variant (the content manifest). */
|
|
74
77
|
contentRoutes: string[];
|
|
78
|
+
/** Configured `deployment.base`, stripped from dev URLs before matching. */
|
|
79
|
+
base?: string;
|
|
80
|
+
/**
|
|
81
|
+
* `content.assets` mounts: top-level dirs served at the site root in dev and
|
|
82
|
+
* copied into the build output, so root-served assets need no relocation.
|
|
83
|
+
*/
|
|
84
|
+
assets?: AssetMount[];
|
|
75
85
|
}
|
|
76
86
|
|
|
77
87
|
/**
|
|
@@ -83,13 +93,13 @@ export interface BlumeIntegrationOptions {
|
|
|
83
93
|
* keep serving HTML.
|
|
84
94
|
*/
|
|
85
95
|
const negotiateMarkdown =
|
|
86
|
-
(routes: ReadonlySet<string
|
|
96
|
+
(routes: ReadonlySet<string>, base?: string) =>
|
|
87
97
|
(req: IncomingMessage, res: ServerResponse, next: () => void): void => {
|
|
88
98
|
if (
|
|
89
99
|
(req.method === "GET" || req.method === "HEAD") &&
|
|
90
100
|
prefersMarkdown(req.headers.accept)
|
|
91
101
|
) {
|
|
92
|
-
const variant = markdownVariantUrl(req.url, routes);
|
|
102
|
+
const variant = markdownVariantUrl(req.url, routes, base);
|
|
93
103
|
if (variant) {
|
|
94
104
|
res.setHeader("Vary", "Accept");
|
|
95
105
|
req.url = variant;
|
|
@@ -108,6 +118,12 @@ export const blumeIntegration = (
|
|
|
108
118
|
options: BlumeIntegrationOptions
|
|
109
119
|
): AstroIntegration => ({
|
|
110
120
|
hooks: {
|
|
121
|
+
"astro:build:done": async ({ dir }) => {
|
|
122
|
+
// Copy in-place asset mounts into the build output, mirroring publicDir.
|
|
123
|
+
if (options.assets?.length) {
|
|
124
|
+
await copyAssetMounts(options.assets, fileURLToPath(dir));
|
|
125
|
+
}
|
|
126
|
+
},
|
|
111
127
|
"astro:config:setup": ({ injectRoute }) => {
|
|
112
128
|
for (const page of options.pages) {
|
|
113
129
|
injectRoute({
|
|
@@ -124,9 +140,16 @@ export const blumeIntegration = (
|
|
|
124
140
|
// Prepend so the rewrite happens before Astro's own request handler,
|
|
125
141
|
// letting the rewritten URL resolve to the `.md` endpoint.
|
|
126
142
|
server.middlewares.stack.unshift({
|
|
127
|
-
handle: negotiateMarkdown(new Set(options.contentRoutes)),
|
|
143
|
+
handle: negotiateMarkdown(new Set(options.contentRoutes), options.base),
|
|
128
144
|
route: "",
|
|
129
145
|
});
|
|
146
|
+
// Serve `content.assets` mounts (Astro only serves publicDir in dev).
|
|
147
|
+
if (options.assets?.length) {
|
|
148
|
+
server.middlewares.stack.unshift({
|
|
149
|
+
handle: serveAssetMounts(options.assets),
|
|
150
|
+
route: "",
|
|
151
|
+
});
|
|
152
|
+
}
|
|
130
153
|
},
|
|
131
154
|
},
|
|
132
155
|
name: "blume",
|
package/src/astro/islands.ts
CHANGED
|
@@ -105,9 +105,13 @@ export const discoverIslands = async (
|
|
|
105
105
|
continue;
|
|
106
106
|
}
|
|
107
107
|
const name = base.replace(ISLAND_FILE, "");
|
|
108
|
-
|
|
108
|
+
// The name is used verbatim as both an MDX tag and an unquoted object key
|
|
109
|
+
// in the generated island map, so it must be a plain PascalCase identifier
|
|
110
|
+
// — a `-`, `.`, or space (e.g. `Time-Picker.tsx`) would otherwise emit a
|
|
111
|
+
// syntax-error module and fail the whole build with no pointer to the file.
|
|
112
|
+
if (!/^[A-Z][A-Za-z0-9_]*$/u.test(name)) {
|
|
109
113
|
warnings.push(
|
|
110
|
-
`Island "${file}" must have a PascalCase filename to be used in MDX (e.g. Counter.tsx → <Counter />); skipping it.`
|
|
114
|
+
`Island "${file}" must have a PascalCase identifier filename to be used in MDX (letters, digits, and underscores only, e.g. Counter.tsx → <Counter />); skipping it.`
|
|
111
115
|
);
|
|
112
116
|
continue;
|
|
113
117
|
}
|
|
@@ -50,7 +50,8 @@ export const prefersMarkdown = (accept: string | null | undefined): boolean => {
|
|
|
50
50
|
*/
|
|
51
51
|
export const markdownVariantUrl = (
|
|
52
52
|
rawUrl: string | null | undefined,
|
|
53
|
-
routes: ReadonlySet<string
|
|
53
|
+
routes: ReadonlySet<string>,
|
|
54
|
+
base?: string
|
|
54
55
|
): string | null => {
|
|
55
56
|
if (!rawUrl) {
|
|
56
57
|
return null;
|
|
@@ -58,11 +59,24 @@ export const markdownVariantUrl = (
|
|
|
58
59
|
const queryIndex = rawUrl.indexOf("?");
|
|
59
60
|
const query = queryIndex === -1 ? "" : rawUrl.slice(queryIndex);
|
|
60
61
|
const rawPath = queryIndex === -1 ? rawUrl : rawUrl.slice(0, queryIndex);
|
|
62
|
+
|
|
63
|
+
// A non-root `deployment.base` prefixes the dev-server URL but not the logical
|
|
64
|
+
// content routes, so strip it before matching and re-add it to the variant.
|
|
65
|
+
const prefix = base && base !== "/" ? base.replace(/\/$/u, "") : "";
|
|
66
|
+
let path = rawPath;
|
|
67
|
+
if (prefix) {
|
|
68
|
+
if (path === prefix || path.startsWith(`${prefix}/`)) {
|
|
69
|
+
path = path.slice(prefix.length) || "/";
|
|
70
|
+
} else {
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
61
75
|
const pathname =
|
|
62
|
-
|
|
76
|
+
path !== "/" && path.endsWith("/") ? path.slice(0, -1) : path;
|
|
63
77
|
if (!routes.has(pathname)) {
|
|
64
78
|
return null;
|
|
65
79
|
}
|
|
66
80
|
const target = pathname === "/" ? "/index" : pathname;
|
|
67
|
-
return `${target}.md${query}`;
|
|
81
|
+
return `${prefix}${target}.md${query}`;
|
|
68
82
|
};
|
package/src/astro/pages.ts
CHANGED
|
@@ -21,7 +21,12 @@ export const discoverPages = async (
|
|
|
21
21
|
return files.map((file) => {
|
|
22
22
|
const rel = relative(pagesRoot, file);
|
|
23
23
|
const withoutExt = rel.slice(0, rel.length - extname(rel).length);
|
|
24
|
-
const parts = withoutExt.split("/")
|
|
24
|
+
const parts = withoutExt.split("/");
|
|
25
|
+
// Only a trailing `index` maps to its parent dir; a folder literally named
|
|
26
|
+
// `index` (e.g. `index/foo.astro`) must keep its segment.
|
|
27
|
+
if (parts.at(-1) === "index") {
|
|
28
|
+
parts.pop();
|
|
29
|
+
}
|
|
25
30
|
const pattern = parts.length === 0 ? "/" : `/${parts.join("/")}`;
|
|
26
31
|
return { entrypoint: file, pattern };
|
|
27
32
|
});
|