blume 0.3.0 → 0.5.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 +1631 -940
- package/dist/cli/index.js.map +62 -50
- package/dist/types/core/data.d.ts +2 -0
- package/dist/types/core/project.d.ts +12 -2
- package/dist/types/core/schema.d.ts +442 -292
- package/dist/types/core/types.d.ts +7 -0
- 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 +34 -51
- package/docs/advanced/blog.mdx +9 -25
- package/docs/advanced/bridge.mdx +74 -0
- package/docs/advanced/changelog.mdx +10 -33
- package/docs/advanced/custom-pages.mdx +21 -78
- package/docs/advanced/meta.ts +8 -1
- package/docs/advanced/migrate.mdx +119 -0
- 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 +95 -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 +12 -41
- package/docs/reference/cli.mdx +47 -30
- package/docs/reference/frontmatter.mdx +7 -5
- package/package.json +11 -1
- package/src/astro/generate.ts +18 -8
- 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 +76 -30
- package/src/cli/args.ts +23 -0
- package/src/cli/commands/build.ts +129 -62
- package/src/cli/commands/check.ts +20 -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 +92 -0
- package/src/cli/log.ts +11 -0
- package/src/cli/prepare.ts +3 -0
- package/src/components/BlumePage.astro +8 -0
- package/src/components/Icon.astro +13 -10
- package/src/components/content/ApiField.astro +75 -0
- package/src/components/content/ParamField.astro +39 -0
- package/src/components/content/RequestField.astro +23 -0
- package/src/components/content/ResponseField.astro +23 -0
- package/src/components/content/Step.astro +1 -1
- 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/layout/Breadcrumbs.astro +7 -2
- package/src/components/layout/NavTree.astro +24 -8
- package/src/components/layout/RootLayout.astro +56 -34
- package/src/components/layout/Search.astro +1 -1
- package/src/components/openapi/ApiOverview.astro +84 -0
- package/src/components/openapi/MethodBadge.astro +28 -0
- package/src/components/openapi/Operation.astro +140 -0
- package/src/components/openapi/ParametersTable.astro +97 -0
- package/src/components/openapi/RequestBody.astro +58 -0
- package/src/components/openapi/RequestPanel.astro +169 -0
- package/src/components/openapi/Responses.astro +91 -0
- package/src/components/openapi/SchemaProperty.astro +118 -0
- package/src/components/openapi/SchemaTable.astro +86 -0
- package/src/components/openapi/helpers.ts +238 -0
- package/src/components/openapi/panel.ts +59 -0
- package/src/components/openapi/snippets.ts +201 -0
- 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 +6 -0
- package/src/core/data.ts +2 -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/project-graph.ts +5 -1
- package/src/core/project.ts +25 -3
- package/src/core/schema.ts +54 -6
- package/src/core/sources/mdx-remote.ts +54 -8
- package/src/core/sources/mintlify.ts +1 -1
- package/src/core/sources/normalize.ts +6 -1
- package/src/core/sources/notion.ts +49 -5
- package/src/core/sources/resolve.ts +28 -6
- package/src/core/sources/sanity.ts +5 -1
- package/src/core/types.ts +7 -0
- 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/config.ts +153 -1
- package/src/migrate/mintlify/content.ts +8 -2
- package/src/migrate/mintlify/index.ts +111 -46
- package/src/migrate/shared.ts +12 -27
- package/src/og/card.ts +14 -2
- package/src/openapi/model.ts +174 -0
- package/src/openapi/parse.ts +48 -0
- package/src/openapi/references.ts +164 -0
- package/src/openapi/render-mdx.ts +76 -0
- package/src/openapi/scalar.ts +15 -103
- package/src/openapi/source.ts +140 -0
- package/src/registry/eject.ts +28 -5
- 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/chrome-icons.ts +22 -0
- package/src/theme/icons.ts +151 -161
- package/src/theme/palette.ts +26 -7
package/docs/content/sources.mdx
CHANGED
|
@@ -3,16 +3,11 @@ title: Content sources
|
|
|
3
3
|
description: Pull docs from local files, a remote repo, or any custom backend — and mix several sources into one site.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
By default Blume reads a folder of `.md`/`.mdx` files. **Content sources** let
|
|
7
|
-
you pull pages from somewhere else — a remote repository, a CMS, or any custom
|
|
8
|
-
backend — and mix several sources into a single site. Sources are read at
|
|
9
|
-
build time; Blume stays static-first.
|
|
6
|
+
By default Blume reads a folder of `.md`/`.mdx` files. **Content sources** let you pull pages from somewhere else — a remote repository, a CMS, or any custom backend — and mix several sources into a single site. Sources are read at build time; Blume stays static-first.
|
|
10
7
|
|
|
11
8
|
## The default
|
|
12
9
|
|
|
13
|
-
With no configuration, Blume scans your content root (`docs` by default) as one
|
|
14
|
-
implicit filesystem source. The top-level `content.root`/`include`/`exclude`
|
|
15
|
-
options still work exactly as before — nothing to change.
|
|
10
|
+
With no configuration, Blume scans your content root (`docs` by default) as one implicit filesystem source. The top-level `content.root`/`include`/`exclude` options still work exactly as before — nothing to change.
|
|
16
11
|
|
|
17
12
|
```ts blume.config.ts
|
|
18
13
|
import { defineConfig } from "blume";
|
|
@@ -24,10 +19,7 @@ export default defineConfig({
|
|
|
24
19
|
|
|
25
20
|
## Multiple sources
|
|
26
21
|
|
|
27
|
-
Add a `content.sources` array to compose sources. Each entry is namespaced by an
|
|
28
|
-
optional `prefix`, so its routes nest under `/<prefix>/…`. When `sources` is
|
|
29
|
-
present it replaces the implicit default, so include a `filesystem` entry for
|
|
30
|
-
your local docs.
|
|
22
|
+
Add a `content.sources` array to compose sources. Each entry is namespaced by an optional `prefix`, so its routes nest under `/<prefix>/…`. When `sources` is present it replaces the implicit default, so include a `filesystem` entry for your local docs.
|
|
31
23
|
|
|
32
24
|
```ts blume.config.ts
|
|
33
25
|
import { defineConfig } from "blume";
|
|
@@ -49,14 +41,11 @@ export default defineConfig({
|
|
|
49
41
|
});
|
|
50
42
|
```
|
|
51
43
|
|
|
52
|
-
If two sources resolve to the same route, Blume reports a `BLUME_DUPLICATE_ROUTE`
|
|
53
|
-
build error — give each source a distinct `prefix`.
|
|
44
|
+
If two sources resolve to the same route, Blume reports a `BLUME_DUPLICATE_ROUTE` build error — give each source a distinct `prefix`.
|
|
54
45
|
|
|
55
46
|
## Remote MDX
|
|
56
47
|
|
|
57
|
-
The built-in `mdx-remote` source fetches raw `.md`/`.mdx` over HTTP. Enumerate
|
|
58
|
-
files either from a GitHub repo subtree (`github`) or explicitly against a raw
|
|
59
|
-
base URL (`url` + `files`):
|
|
48
|
+
The built-in `mdx-remote` source fetches raw `.md`/`.mdx` over HTTP. Enumerate files either from a GitHub repo subtree (`github`) or explicitly against a raw base URL (`url` + `files`):
|
|
60
49
|
|
|
61
50
|
```ts blume.config.ts
|
|
62
51
|
{
|
|
@@ -67,34 +56,19 @@ base URL (`url` + `files`):
|
|
|
67
56
|
}
|
|
68
57
|
```
|
|
69
58
|
|
|
70
|
-
A private repo's token is read from the `GITHUB_TOKEN` environment variable — it
|
|
71
|
-
is never inlined into your config or generated output.
|
|
59
|
+
A private repo's token is read from the `GITHUB_TOKEN` environment variable — it is never inlined into your config or generated output.
|
|
72
60
|
|
|
73
|
-
Remote pages are rendered with full MDX-plus-component fidelity: their bodies are
|
|
74
|
-
materialized into a hidden staging directory and rendered through Astro
|
|
75
|
-
alongside your local docs, so callouts, tabs, and every other Blume component
|
|
76
|
-
keep working.
|
|
61
|
+
Remote pages are rendered with full MDX-plus-component fidelity: their bodies are materialized into a hidden staging directory and rendered through Astro alongside your local docs, so callouts, tabs, and every other Blume component keep working.
|
|
77
62
|
|
|
78
63
|
### Caching and offline builds
|
|
79
64
|
|
|
80
|
-
Each remote source keeps a snapshot under `.blume/cache/<source>/`. If a fetch
|
|
81
|
-
fails — a network blip or a CMS outage — Blume serves the last-known-good
|
|
82
|
-
snapshot with a warning rather than failing the build. The cache lives inside
|
|
83
|
-
`.blume/` and is regenerated, never committed.
|
|
65
|
+
Each remote source keeps a snapshot under `.blume/cache/<source>/`. If a fetch fails — a network blip or a CMS outage — Blume serves the last-known-good snapshot with a warning rather than failing the build. The cache lives inside `.blume/` and is regenerated, never committed.
|
|
84
66
|
|
|
85
|
-
In dev, remote content is fetched once and frozen for the session; restart the
|
|
86
|
-
dev server to refresh it. Local filesystem sources hot-reload as usual. To poll
|
|
87
|
-
a remote source for changes instead, set `pollInterval` (seconds) on it — the
|
|
88
|
-
dev server re-fetches on that interval and reloads only when the content
|
|
89
|
-
actually changes. Leave it unset to avoid hitting the API while you work.
|
|
67
|
+
In dev, remote content is fetched once and frozen for the session; restart the dev server to refresh it. Local filesystem sources hot-reload as usual. To poll a remote source for changes instead, set `pollInterval` (seconds) on it — the dev server re-fetches on that interval and reloads only when the content actually changes. Leave it unset to avoid hitting the API while you work.
|
|
90
68
|
|
|
91
69
|
## GitHub Releases
|
|
92
70
|
|
|
93
|
-
The built-in `github-releases` source turns a repo's releases into a changelog:
|
|
94
|
-
each release becomes a `type: changelog` entry, so your release notes _are_ your
|
|
95
|
-
changelog — nothing to write twice. Combined with the generated
|
|
96
|
-
[changelog timeline](/docs/advanced/changelog), publishing a GitHub release
|
|
97
|
-
ships a changelog entry.
|
|
71
|
+
The built-in `github-releases` source turns a repo's releases into a changelog: each release becomes a `type: changelog` entry, so your release notes _are_ your changelog — nothing to write twice. Combined with the generated [changelog timeline](/docs/advanced/changelog), publishing a GitHub release ships a changelog entry.
|
|
98
72
|
|
|
99
73
|
```ts blume.config.ts
|
|
100
74
|
import { defineConfig } from "blume";
|
|
@@ -117,25 +91,13 @@ export default defineConfig({
|
|
|
117
91
|
});
|
|
118
92
|
```
|
|
119
93
|
|
|
120
|
-
Each release maps to the changelog fields automatically: its name (or tag)
|
|
121
|
-
becomes the title, its published date drives the timeline order, the tag becomes
|
|
122
|
-
`changelog.version`, and prereleases are tagged `Prerelease` (others `Release`).
|
|
123
|
-
The notes render as the entry body. Give the source a `prefix` so its release
|
|
124
|
-
pages nest under a route like `/changelog/v1-2-0`.
|
|
94
|
+
Each release maps to the changelog fields automatically: its name (or tag) becomes the title, its published date drives the timeline order, the tag becomes `changelog.version`, and prereleases are tagged `Prerelease` (others `Release`). The notes render as the entry body. Give the source a `prefix` so its release pages nest under a route like `/changelog/v1-2-0`.
|
|
125
95
|
|
|
126
|
-
A private repo authenticates with the `GITHUB_TOKEN` environment variable — the
|
|
127
|
-
same token the other GitHub features use, never inlined into your config. Like
|
|
128
|
-
every remote source it's cached under `.blume/cache/<source>/` and served
|
|
129
|
-
offline if the API is unreachable. Because a changelog is supplementary, a fetch
|
|
130
|
-
failure with no cache (say a CI build without a token) degrades to an empty
|
|
131
|
-
changelog with a warning rather than failing the build — set `GITHUB_TOKEN` in
|
|
132
|
-
your CI and deploy environments to populate it.
|
|
96
|
+
A private repo authenticates with the `GITHUB_TOKEN` environment variable — the same token the other GitHub features use, never inlined into your config. Like every remote source it's cached under `.blume/cache/<source>/` and served offline if the API is unreachable. Because a changelog is supplementary, a fetch failure with no cache (say a CI build without a token) degrades to an empty changelog with a warning rather than failing the build — set `GITHUB_TOKEN` in your CI and deploy environments to populate it.
|
|
133
97
|
|
|
134
98
|
## Sanity
|
|
135
99
|
|
|
136
|
-
The built-in `sanity` source runs a GROQ query and maps each document's fields
|
|
137
|
-
to frontmatter and its Portable Text body to Markdown. The `@sanity/client`
|
|
138
|
-
package is an optional peer dependency — install it only if you use this source.
|
|
100
|
+
The built-in `sanity` source runs a GROQ query and maps each document's fields to frontmatter and its Portable Text body to Markdown. The `@sanity/client` package is an optional peer dependency — install it only if you use this source.
|
|
139
101
|
|
|
140
102
|
```ts blume.config.ts
|
|
141
103
|
import { defineConfig } from "blume";
|
|
@@ -158,17 +120,11 @@ export default defineConfig({
|
|
|
158
120
|
});
|
|
159
121
|
```
|
|
160
122
|
|
|
161
|
-
A read token for a private dataset comes from the `SANITY_TOKEN` environment
|
|
162
|
-
variable. Custom Portable Text block types map to Blume components through the
|
|
163
|
-
adapter's `serializers` option, available when you construct `sanitySource`
|
|
164
|
-
directly via a [custom source](#custom-sources).
|
|
123
|
+
A read token for a private dataset comes from the `SANITY_TOKEN` environment variable. Custom Portable Text block types map to Blume components through the adapter's `serializers` option, available when you construct `sanitySource` directly via a [custom source](#custom-sources).
|
|
165
124
|
|
|
166
125
|
## Notion
|
|
167
126
|
|
|
168
|
-
The built-in `notion` source turns a Notion database into a collection: each row
|
|
169
|
-
becomes a page, its properties become frontmatter, and its block tree becomes
|
|
170
|
-
MDX. Callouts, toggles, columns, and code blocks map to the matching Blume
|
|
171
|
-
components. `@notionhq/client` is an optional peer dependency.
|
|
127
|
+
The built-in `notion` source turns a Notion database into a collection: each row becomes a page, its properties become frontmatter, and its block tree becomes MDX. Callouts, toggles, columns, and code blocks map to the matching Blume components. `@notionhq/client` is an optional peer dependency.
|
|
172
128
|
|
|
173
129
|
```ts blume.config.ts
|
|
174
130
|
import { defineConfig } from "blume";
|
|
@@ -190,29 +146,14 @@ export default defineConfig({
|
|
|
190
146
|
});
|
|
191
147
|
```
|
|
192
148
|
|
|
193
|
-
The integration token comes from the `NOTION_TOKEN` environment variable (share
|
|
194
|
-
the database with your integration). By default every page is imported; set
|
|
195
|
-
`publishedValue` to make the `Status` property a publish gate — any other value
|
|
196
|
-
then maps to `draft: true`, which production builds drop. **Notion image URLs
|
|
197
|
-
are signed and expire**, so the adapter downloads them at build time into the
|
|
198
|
-
site's assets and rewrites the references — a CMS image never rots a static
|
|
199
|
-
build.
|
|
149
|
+
The integration token comes from the `NOTION_TOKEN` environment variable (share the database with your integration). By default every page is imported; set `publishedValue` to make the `Status` property a publish gate — any other value then maps to `draft: true`, which production builds drop. **Notion image URLs are signed and expire**, so the adapter downloads them at build time into the site's assets and rewrites the references — a CMS image never rots a static build.
|
|
200
150
|
|
|
201
151
|
## Preview and sync
|
|
202
152
|
|
|
203
153
|
Two flags control how remote content is fetched and what's included:
|
|
204
154
|
|
|
205
|
-
- **`--preview`** on `blume dev` or `blume build` renders drafts and pulls
|
|
206
|
-
|
|
207
|
-
and Notion stops filtering by `Status`. Production builds without the flag
|
|
208
|
-
exclude drafts as usual, so a preview build is a safe way to review
|
|
209
|
-
unpublished work before it ships.
|
|
210
|
-
- **`blume sync`** re-fetches every remote source and regenerates the runtime.
|
|
211
|
-
Dev is cache-first — a remote source is fetched once and served from
|
|
212
|
-
`.blume/cache` on restart (fast and offline-tolerant), so `blume sync` is how
|
|
213
|
-
you pull the latest CMS content without restarting the dev server (a running
|
|
214
|
-
server hot-reloads). Add `--force` to drop the cache first, or set
|
|
215
|
-
`pollInterval` on a source to refresh automatically.
|
|
155
|
+
- **`--preview`** on `blume dev` or `blume build` renders drafts and pulls unpublished CMS content — Sanity switches to its `previewDrafts` perspective, and Notion stops filtering by `Status`. Production builds without the flag exclude drafts as usual, so a preview build is a safe way to review unpublished work before it ships.
|
|
156
|
+
- **`blume sync`** re-fetches every remote source and regenerates the runtime. Dev is cache-first — a remote source is fetched once and served from `.blume/cache` on restart (fast and offline-tolerant), so `blume sync` is how you pull the latest CMS content without restarting the dev server (a running server hot-reloads). Add `--force` to drop the cache first, or set `pollInterval` on a source to refresh automatically.
|
|
216
157
|
|
|
217
158
|
```sh
|
|
218
159
|
blume dev --preview # author workflow: see drafts live
|
|
@@ -223,9 +164,7 @@ blume sync --force # ...ignoring any cached snapshot
|
|
|
223
164
|
|
|
224
165
|
## Custom sources
|
|
225
166
|
|
|
226
|
-
Any object implementing the `ContentSource` interface can be passed directly,
|
|
227
|
-
which is how an adapter with custom serializers — or any backend not built in —
|
|
228
|
-
plugs in without its SDK touching the core install:
|
|
167
|
+
Any object implementing the `ContentSource` interface can be passed directly, which is how an adapter with custom serializers — or any backend not built in — plugs in without its SDK touching the core install:
|
|
229
168
|
|
|
230
169
|
```ts blume.config.ts
|
|
231
170
|
import { defineConfig } from "blume";
|
|
@@ -254,6 +193,4 @@ export default defineConfig({
|
|
|
254
193
|
});
|
|
255
194
|
```
|
|
256
195
|
|
|
257
|
-
A source normalizes its native shape (Portable Text, Notion blocks, remote HTML)
|
|
258
|
-
to Markdown/MDX text, so the same components and markdown features apply no
|
|
259
|
-
matter where a page comes from.
|
|
196
|
+
A source normalizes its native shape (Portable Text, Notion blocks, remote HTML) to Markdown/MDX text, so the same components and markdown features apply no matter where a page comes from.
|
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 no client framework JS. :::
|
|
402
342
|
|
|
403
343
|
```md
|
|
404
|
-
:::info
|
|
405
|
-
The core theme ships zero client JavaScript.
|
|
406
|
-
:::
|
|
344
|
+
:::info The core theme ships no client framework JS. :::
|
|
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 ships no client framework JS 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
|
-
|
|
77
|
-
- **
|
|
78
|
-
- **Eject** — `blume eject` produces a standalone Astro project that still uses
|
|
79
|
-
the `blume` package.
|
|
51
|
+
- **Customization** — component overrides, React islands, custom pages, theme tokens, and a source-component registry via `blume add`.
|
|
52
|
+
- **Migration** — [`blume migrate mintlify | starlight | nextra | fumadocs`](/docs/advanced/migrate), or run `blume dev` on a Mintlify project as-is with [bridge mode](/docs/advanced/bridge).
|
|
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
|
|