@ox-content/vite-plugin#
Environment API 対応の、Ox Content 向けベース Vite プラグインです。
インストール#
vp install @ox-content/vite-plugin
@ox-content/vite-plugin はすでに @ox-content/napi に依存するので、Vite プラグインを使うときは別途 vp install @ox-content/napi は不要です。
基本的な使い方#
// vite.config.ts
import { defineConfig } from "vite";
import { oxContent } from "@ox-content/vite-plugin";
export default defineConfig({
plugins: [
oxContent({
srcDir: "docs",
}),
],
});
VitePress からの移行#
すでに VitePress サイトがあるときは、編集可能な ox-content オプションオブジェクトを生成します。
vpx oxct migrate vitepress .vitepress/config.ts \
--src-dir docs \
--out-dir dist \
--out ox-content.config.ts
CLI は @ox-content/vite-plugin が入れる oxct バイナリから実行します。
vpx oxct migrate vitepress .vitepress/config.ts --out ox-content.config.ts
生成される ox-content.config.ts は、これらの設定を ox-content へ写します。
title/themeConfig.siteTitle→ssg.siteNamebase→basethemeConfig.sidebar→ssg.navigationthemeConfig.socialLinks/themeConfig.footer/themeConfig.logo→ssg.themethemeConfig.search.placeholder→search.placeholder
ランディングページでは、VitePress 風の layout: home frontmatter は ox-content の layout: entry と同じ扱いになります。
オプション#
非標準機能のどれがオプトインかを含む、まとめた既定表は 組み込み機能 を見てください。
srcDir#
- 型:
string - 既定:
'docs'
Markdown ファイルのソースディレクトリです。
extensions#
- 型:
string[] - 既定:
['.md', '.markdown', '.mdx']
Vite プラグイン、SSG、開発サーバ、検索インデックス、OG ビューアが処理する Markdown 風ファイル拡張子です。
outDir#
- 型:
string - 既定:
'dist'
ビルド成果物の出力ディレクトリです。
ssg#
- 型:
SsgOptions | boolean - 既定:
{ enabled: true }
SSG(静的サイト生成)オプションです。既定では、ox-content はビルド中に各 Markdown ファイルの静的 HTML を生成します。
oxContent({
ssg: {
enabled: true,
extension: ".html",
clean: false,
},
});
SsgOptions#
| オプション | 型 | 既定 | 説明 |
|---|---|---|---|
enabled |
boolean |
true |
SSG モードのオン / オフ |
extension |
string |
'.html' |
出力ファイル拡張子 |
clean |
boolean |
false |
ビルド前に出力ディレクトリを消す |
bare |
boolean |
false |
素の HTML 出力(ナビなし、スタイルなし) |
Bare モード(ベンチマーク向け)#
oxContent({
ssg: {
bare: true, // ナビ / スタイルなしの最小 HTML
},
});
SSG を切る#
oxContent({
ssg: false, // SSG を切り、モジュール変換器としてだけ使う
});
Vite 経由で Markdown を import しない独自ホストでも、公開 OxContentOptions
から同じパイプラインを実行し、構造化された TransformResult を受け取れます。
プラグインの transform フックをキャストしたり、生成モジュールの
export const html = ... をパースしたりする必要はありません。
import { renderMarkdown } from "@ox-content/vite-plugin";
const result = await renderMarkdown("# Hi", "/virtual/article.md", {
ssg: false,
highlight: false,
});
result.html;
result.frontmatter;
result.toc;
.md / .mdx の判定は Vite プラグインと同じ (resolveMdxForFilePath) で、
組み込みオプションの既定値も oxContent() と一致します。複数ドキュメントで
オプション解決を一度だけにしたいときは createMarkdownProcessor(options) を
使い、processor.render(source, filePath) を呼んでください。
ssg: false、renderMarkdown()、transformAllPlugins() が返すのは
マークアップだけです。その HTML を描画するホストで公式の機能スタイルシートを
import してください。crate の CSS をアプリにコピーしないでください。
コンポーネント CSS を見てください。
@import "@ox-content/vite-plugin/styles/core.css";
@import "@ox-content/vite-plugin/styles/markdown-tables.css";
@import "@ox-content/vite-plugin/styles/magic-links.css";
@import "@ox-content/vite-plugin/styles/social.css";
@import "@ox-content/vite-plugin/styles/twitter-full.css";
@import "@ox-content/vite-plugin/styles/reader-chrome.css";
既存の prose theme に、keyboard accessible なレスポンシブ Markdown table
だけを足したい場合は、package root と styles/core.css ではなく
styles/markdown-tables.css と
@ox-content/vite-plugin/markdown-tables を使ってください。
独自ホストは oxContentCustomHost() で Vite lifecycle を Ox Content に任せられます。
dev/build で host module を SSR load し、route dispatch、response cache、
dependency invalidation、manifest 対応の document asset tag、self-hosted asset、
redirect、Markdown 併記、協調 writer を持ちます。
独自ホスト lifecycle と
Document assets を見てください。
framework integration がすでに Vite plugin を持っている場合も、buildSsg() なしで
低レベルのリソース指紋、Markdown 併記、フィード、sitemap、git lastmod helper を
再利用できます。SSG 出力プリミティブ を見てください。
Environment API の runtime 解決#
oxContent() は Vite の Environment API で Markdown environment を設定します。
Vite が Deno または Bun 上で動いているときは、対応する deno / bun
resolve condition を追加し、build target は runtime neutral にします。既存の
environment condition は残すので、アプリ側の conditional exports と併用できます。
import { createMarkdownEnvironment } from "@ox-content/vite-plugin";
export default defineConfig({
environments: {
markdown: createMarkdownEnvironment(resolvedOxContentOptions),
},
});
Fetch router と middleware#
Vite dev server なしで Markdown ページを描画したいホストでは、
@ox-content/vite-plugin/router を使えます。router は標準 Fetch の
Request / Response API ベースなので、同じ handler を Deno、Bun、
Workers 風ホスト、Node adapter で使えます。
// deno.ts
import { createOxContentFetchHandler } from "@ox-content/vite-plugin/router";
Deno.serve(
createOxContentFetchHandler(
{
srcDir: "content",
ssg: { routePrefix: "blog" },
},
Deno.cwd(),
),
);
// bun.ts
import { createOxContentFetchHandler } from "@ox-content/vite-plugin/router";
const fetch = createOxContentFetchHandler(
{
srcDir: "content",
base: "/docs/",
ssg: { routePrefix: "blog" },
},
import.meta.dir,
);
Bun.serve({ fetch });
framework adapter や独自 server では、組み込み renderer の前後に middleware を合成できます。
import { createOxContentMiddleware } from "@ox-content/vite-plugin/router";
const oxContentPages = createOxContentMiddleware({ srcDir: "content" }, projectRoot, {
middleware: [
async (context, next) => {
if (context.match.routePathname.startsWith("/drafts/")) {
return new Response("Not Found", { status: 404 });
}
const response = await next();
if (!response) return undefined;
const headers = new Headers(response.headers);
headers.set("x-ox-route", context.match.routePathname);
return new Response(response.body, { headers, status: response.status });
},
],
});
gfm#
- 型:
boolean - 既定:
true
GitHub Flavored Markdown 拡張を有効にします。
codeAnnotations#
- 型:
boolean | CodeAnnotationsOptions - 既定:
false
フェンス付きコードブロック向けの、オプトインのコード注釈を有効にします。
既定では Ox Content は設定可能な属性構文を使います。VitePress 互換のフェンスメタデータとインライン記法にオプトインすることも、両方同時にオンにすることもできます。
oxContent({
highlight: true,
codeAnnotations: {
notation: "both",
},
});
既定 metaKey の属性構文:
```ts annotate="highlight:1,6;warning:2;error:3"
export function loadUser(input: string) {
if (!input) console.warn("missing payload");
throw new Error("missing id");
}
const user = loadUser(payload);
console.log(user);
```
VitePress 互換構文:
```ts:line-numbers=10 {1,4} [config.ts]
const user = loadUser(payload);
console.warn("Deprecated")
throw new Error("boom")
```
描画例:
export function loadUser(input: string) {
if (!input) console.warn("missing payload");
throw new Error("missing id");
}
const user = loadUser(payload);
console.log(user);
属性名も変えられます。
oxContent({
codeAnnotations: {
metaKey: "markers",
},
});
描画例は Code Annotations の例 を見てください。
toc#
- 型:
boolean - 既定:
true
目次を生成します。
embeds#
- 型:
BuiltinEmbedOptions | false - 既定:
{ github: true, openGraph: true, pm: false, spotify: false, appleMusic: false, speakerDeck: false, audio: false, video: false, stackBlitz: false, twitter: false, reddit: false, bluesky: false, webContainer: false }
組み込みの静的埋め込みは変換時に描画され、クライアント側 JavaScript は使いません。非標準の埋め込みはオプトインです。既定表と描画例の全体は 埋め込み を見てください。
<GitHub repo="ubugeeei-prod/ox-content" />
<GitHub permalink="https://github.com/ubugeeei-prod/ox-content/blob/278098b/README.md#L1-L12" />
<GitHub repo="ubugeeei-prod/ox-content" path="README.md" ref="main" loc="1-12" />
<OgCard url="https://github.com/ubugeeei-prod/ox-content" />
permalink、url、href は GitHub の blob URL を受け付けます。#L1-L12 フラグメントはソース行範囲として使います。完全なパーマリンクを貼りたくないときは repo、path、ref、loc も使えます。ソース埋め込みは GitHub contents API を取り、Open Graph プレビューではなくコードを直接描画します。
すべての埋め込みを切るか、各取得器を設定します。
oxContent({
embeds: {
github: {
token: process.env.GITHUB_TOKEN,
maxSourceBytes: 200000,
maxSourceLines: 120,
},
openGraph: {
timeout: 5000,
},
pm: true,
reddit: true,
},
});
oxContent({
embeds: false,
});
組み込み埋め込みのスタイル#
組み込み埋め込みのマークアップは安定した CSS クラスを使うので、生成 HTML はクライアント側 JavaScript なしでテーマできます。
リポジトリカードのクラス:
.ox-github-card.ox-github-header.ox-github-icon.ox-github-repo.ox-github-description.ox-github-stats.ox-github-stat.ox-github-language
ソースコードカードのクラス:
.ox-github-code.ox-github-code-header.ox-github-code-title.ox-github-code-loc.ox-github-code-block.ox-github-code-line.ox-github-code-line-number.ox-github-code-line-content
Open Graph カードのクラス:
.ox-ogp-card.ox-ogp-simple.ox-ogp-content.ox-ogp-title.ox-ogp-description.ox-ogp-image.ox-ogp-meta.ox-ogp-domain.ox-ogp-favicon
.ox-github-card,
.ox-github-code,
.ox-ogp-card {
border-color: var(--my-border-color);
}
.ox-github-code-line-number,
.ox-ogp-domain {
color: var(--my-muted-color);
}
docs#
- 型:
DocsOptions | false - 既定:
{ enabled: true }
ソースドキュメント生成オプションです。切るときは false です。
生成 API ページはいま、要約統計、シグネチャバッジ、1 行のシンボル概要、展開できる詳細、ラベル付き例を含みます。集計件数を持つ機械可読の docs.json ペイロードも Markdown の横に出るので、独自ビューアはソースを再パースせずより豊かな体験を作れます。
oxContent({
docs: {
enabled: true,
src: ["./src"],
out: "docs/api",
include: ["**/*.ts"],
exclude: ["**/*.test.*"],
format: "markdown",
toc: true,
groupBy: "file",
},
});
DocsOptions#
| オプション | 型 | 既定 | 説明 |
|---|---|---|---|
enabled |
boolean |
true |
docs 生成のオン / オフ |
src |
string[] |
['./src'] |
走査するソースディレクトリ |
out |
string |
'docs/api' |
出力ディレクトリ |
include |
string[] |
JS/TS ソース glob | 含めるファイル |
exclude |
string[] |
['**/*.test.*', '**/*.spec.*'] |
除くファイル |
format |
'markdown' | 'json' | 'html' |
'markdown' |
出力形式 |
private |
boolean |
false |
@private メンバーを含める |
toc |
boolean |
true |
目次を生成する |
groupBy |
'file' | 'category' |
'file' |
ファイルまたはカテゴリでグループ |
docs 生成を切る#
oxContent({
docs: false, // 組み込み docs 生成をオプトアウト
});
search#
- 型:
SearchOptions | boolean - 既定:
{ enabled: true }
全文検索オプションです。Ox Content は BM25 スコア付きの、Rust 駆動の組み込み検索エンジンを載せます。
oxContent({
search: {
enabled: true,
limit: 10,
prefix: true,
placeholder: "Search documentation...",
hotkey: "/",
},
});
SearchOptions#
| オプション | 型 | 既定 | 説明 |
|---|---|---|---|
enabled |
boolean |
true |
検索機能のオン / オフ |
limit |
number |
10 |
検索結果の上限 |
prefix |
boolean |
true |
オートコンプリート向けプレフィックス一致 |
placeholder |
string |
'Search documentation...' |
検索入力のプレースホルダ |
hotkey |
string |
'/' |
検索を開くキーボードショートカット |
動き方#
- ビルド時: プラグインはすべての Markdown を走査し、Rust ベースの検索エンジンでインデックスを作る
- インデックス保存: インデックスは出力ディレクトリの
search-index.jsonに書く - クライアント側検索: 検索インデックスは必要になったときに読み、検索はすべてクライアント側
機能#
- BM25 スコア: 業界標準の関連度順位アルゴリズム
- 複数フィールド検索: タイトル、見出し、本文、コードを異なる重みで索引
- 日本語 / CJK 対応: CJK 文字の適切なトークン化
- プレフィックス一致: オートコンプリート向けタイプアヘッド
- スコープ付きクエリ:
@api transformのようにプレフィックスして区画で結果を制限 - 依存ゼロ: 外部検索サービスは不要
検索を切る#
oxContent({
search: false, // 組み込み検索を切る
});
独自検索 UI と使う#
仮想モジュール経由で検索インデックスにプログラムから触れます。
import { search, searchOptions } from "virtual:ox-content/search";
// Search the index
const results = await search("query text", { limit: 5 });
// Scope search to the API reference
const apiResults = await search("@api transform", { limit: 5 });
// Results include:
// - id: document ID
// - title: document title
// - url: document URL
// - score: relevance score
// - snippet: text snippet with context
collections#
- 型:
CollectionsOptions | boolean - 既定:
{ content: { source: "**/*" } }
コレクションは Markdown frontmatter とルートメタデータを virtual:ox-content/collections 経由で出します。その仮想モジュールを import したときだけビルドします。既定ペイロードはメタデータのみです。Ox Content はディレクトリ歩行、ソースパターンフィルタ、frontmatter パース、ルートパス生成、タイトル取り出しにネイティブ Rust マニフェストビルダを使うので、大きな Markdown 木はファイルごとの JavaScript / NAPI 往復を避け、すべての Markdown を HTML に描画しません。
// vite.config.ts
import { defineConfig } from "vite";
import { defineCollection, oxContent } from "@ox-content/vite-plugin";
export default defineConfig({
plugins: [
oxContent({
srcDir: "content",
collections: {
blog: defineCollection({
source: "blog/**/*.md",
}),
docs: defineCollection({
source: "docs/**/*.md",
include: ["body"],
}),
},
}),
],
});
import { queryCollection } from "virtual:ox-content/collections";
const posts = await queryCollection("blog")
.where("draft", "=", false)
.order("date", "DESC")
.select("title", "path", "description")
.all();
const page = await queryCollection("docs").path("/docs/getting-started").first();
大きなサイトでは include は意図して明示です。
| フィールド | コスト |
|---|---|
body |
除いた生 Markdown を仮想モジュールに埋め込む。 |
html |
ネイティブ Markdown 変換を走らせ、HTML を埋め込む。 |
toc |
ネイティブ Markdown 変換を走らせ、TOC を埋め込む。 |
シンタックスハイライトや Mermaid 描画のような、ページ単位の完全な JavaScript 後処理では、Markdown モジュールを直接 import してください。コレクションの html はクエリペイロード向けに最適化しています。
コレクション全体を切るときは collections: false です。
Environment API#
プラグインは、SSG に寄せた描画のため、Vite の Environment API で markdown 環境を作ります。
HMR 対応#
開発中、Markdown はホットリロードされます。プラグインは独自 HMR イベントを送ります。
// Client-side
if (import.meta.hot) {
import.meta.hot.on("ox-content:update", (data) => {
console.log("Markdown updated:", data.file);
});
}
仮想モジュール#
プラグインは次の仮想モジュールを提供します。
virtual:ox-content/config— 解決済みプラグイン設定virtual:ox-content/runtime— ランタイムユーティリティvirtual:ox-content/search— 検索機能virtual:ox-content/collections— コレクションクエリヘルパー
import config from "virtual:ox-content/config";
import { useMarkdown, withBase, withoutBase } from "virtual:ox-content/runtime";
import { search, searchOptions } from "virtual:ox-content/search";
import { queryCollection } from "virtual:ox-content/collections";
const assetUrl = withBase("/og.png");
const routePath = withoutBase("/docs/guide");
// Use the search function
const results = await search("query", { limit: 10 });
const page = await queryCollection("content").path("/guide").first();