# REST API (https://docs.blode.md/api/overview) Programmatic access to projects, deployments, and domains. The base URL for all requests is `https://api.blode.md`. > [!NOTE] > The CLI handles deployments automatically. Use the REST API for custom > integrations or tooling built on top of blodemd. ## Authentication Every endpoint uses the Supabase user session token issued by `blodemd login`: ``` Authorization: Bearer ``` The CLI attaches this header automatically. ## Error format All errors return JSON with an `error` string and an optional `issues` field for validation errors. ```json { "error": "string", "issues": [] } ``` --- ## Health | Method | Path | Description | | ------ | --------- | --------------------------------- | | GET | `/health` | Returns `{ ok: true, timestamp }` | --- ## Projects | Method | Path | Description | | ------ | ---------------------- | -------------------------------------------- | | GET | `/projects/` | List all projects for the authenticated user | | POST | `/projects/` | Create a project | | GET | `/projects/:projectId` | Get a project | | PATCH | `/projects/:projectId` | Update a project | **POST /projects/ — request body** - `name` (type: string): Display name for the project. - `slug` (type: string): URL-safe identifier. Used as the subdomain at `{slug}.blode.md`. - `description` (type: string, default: undefined): Optional short description. Returns the created project. **PATCH /projects/:projectId — request body** - `name` (type: string, default: undefined): New display name. - `description` (type: string, default: undefined): New description. - `deploymentName` (type: string, default: undefined): Override the active deployment label. --- ## Deployments Deployments follow a three-step flow: create → upload files → finalize. | Method | Path | Description | | ------ | -------------------------------------------------- | --------------------- | | POST | `/projects/slug/:slug/deployments` | Create a deployment | | POST | `/projects/slug/:slug/deployments/:id/files/batch` | Upload files in batch | | POST | `/projects/slug/:slug/deployments/:id/finalize` | Finalize and promote | **POST /projects/slug/:slug/deployments — request body** - `branch` (type: string, default: "main"): Git branch name. - `commitMessage` (type: string, default: undefined): Commit message attached to this deployment. - `environment` (type: string, default: undefined): Deployment environment label. **POST .../files/batch — request body** **POST .../finalize — request body** - `promote` (type: boolean, default: true): Promote this deployment to production immediately. --- ## Domains | Method | Path | Description | | ------ | ----------------------------------------------------- | ---------------------------- | | GET | `/projects/:projectId/domains` | List domains | | POST | `/projects/:projectId/domains` | Add a custom domain | | DELETE | `/projects/:projectId/domains/:domainId` | Remove a domain | | GET | `/projects/:projectId/domains/:domainId/verification` | Get DNS verification records | | POST | `/projects/:projectId/domains/:domainId/verify` | Trigger domain verification | **POST /projects/:projectId/domains — request body** - `hostname` (type: string): The fully-qualified domain name to add, e.g. `docs.example.com`. - `pathPrefix` (type: string, default: undefined): Mount the docs at a subpath, e.g. `/docs`. # blodemd analytics (https://docs.blode.md/cli/analytics) Manage tenant analytics integrations (GA4, PostHog) from the CLI. `blodemd analytics` reads and writes the per-project analytics config that the dashboard exposes at **Settings → Analytics**. Use it to script rollouts, wire analytics into CI, or keep your docs repo the source of truth. ## Subcommands ```bash title="Read current config" blodemd analytics get [--project ] [--json] ``` ```bash title="Set Google Analytics 4" blodemd analytics set ga4 [--project ] ``` ```bash title="Set PostHog" blodemd analytics set posthog [--host ] [--project ] ``` ```bash title="Remove a provider" blodemd analytics unset [--project ] ``` The project slug is resolved in this order: `--project`, `BLODEMD_PROJECT`, `slug` in your local `docs.json`. Run from inside your docs repo and you never need to pass it. ## Examples ```bash # Set GA4 for the project in the current directory blodemd analytics set ga4 G-ABC123DEFG # Set PostHog with the EU cloud host blodemd analytics set posthog phc_abc123def456 --host `eu.i.posthog.com` # Check what's configured, as JSON, so you can pipe it blodemd analytics get --json # Remove only PostHog, keep GA4 blodemd analytics unset posthog ``` ## Options - `--project ` (type: string): Project slug. Defaults to BLODEMD_PROJECT or docs.json. - `--api-url ` (type: string): Blode.md API URL. Override for self-hosted deployments. - `--json` (type: boolean, default: false): Print the analytics config as JSON (only on `get`). - `--host ` (type: string): PostHog host (only on `set posthog`). Defaults to `us.i.posthog.com.` ## Validation The CLI validates inputs before hitting the API: - **GA4 measurement ID** must match `G-XXXXXXXXXX` (uppercase, 4–20 alphanumerics). - **PostHog project key** must start with `phc_` and be at least 24 characters. Personal API keys (`phx_`) are rejected — they have far more privilege than the project key needs and would leak to the browser. - **PostHog host** must be an `https://` URL. ## Authentication `blodemd analytics` requires you to be logged in. Run `blodemd login` if the CLI reports you are not authenticated. # blodemd dev (https://docs.blode.md/cli/dev) Start a local development server for real-time preview. Run the full Blode.md rendering engine locally so you can preview your documentation as you write. ```bash blodemd dev ``` ## How it works The dev server starts a local Next.js instance that renders your documentation with the same engine used in production. A file watcher monitors your docs directory and triggers automatic browser refreshes when content changes. Changes to `docs.json` trigger a full server reload. ## Options - `--no-open` (type: boolean, default: false): Do not open the browser automatically when the server starts. ## Examples ```bash title="Start with defaults" blodemd dev ``` ```bash title="Custom port" blodemd dev --port 4000 ``` ```bash title="Specific directory, no browser" blodemd dev --dir ./my-docs --no-open ``` ## File watching The dev server watches all files in your docs directory for changes: - **Content changes** (`.mdx`, `.md`, `.json` files) trigger a hot reload in the browser. - **Config changes** (`docs.json`) trigger a full server reload to pick up navigation, branding, and API config updates. > [!INFO] > The dev server requires a valid `docs.json` in your docs directory. Run > `blodemd new` first if you are starting from scratch. # blodemd login (https://docs.blode.md/cli/login) Authenticate with Blode.md via GitHub in your browser. Authenticate your CLI session so you can deploy documentation with `blodemd push`. ```bash blodemd login ``` ## How it works `blodemd login` opens your browser to sign in with GitHub via Supabase OAuth (PKCE). After you authorize, the CLI receives an access token and stores it locally. No API keys, ever. The CLI starts a temporary local server on port 8787 to receive the OAuth callback. If the browser does not open automatically, copy the printed URL manually. ## Options - `--port ` (type: number, default: 8787): Port for the local OAuth callback server. - `--timeout ` (type: number, default: 180): How long to wait for browser authorization before timing out. - `--no-open` (type: boolean, default: false): Print the authorization URL instead of opening the browser. ## Examples ```bash title="Browser sign-in" blodemd login ``` ```bash title="Custom port and no browser" blodemd login --port 9090 --no-open ``` ## Credential storage Credentials are stored at `~/.config/blodemd/credentials.json`. The OAuth session includes a refresh token so the CLI can renew your session automatically. Run `blodemd logout` to remove stored credentials. # blodemd logout (https://docs.blode.md/cli/logout) Remove stored credentials from your local machine. Delete the credentials file saved by `blodemd login` from your local machine. ```bash blodemd logout ``` The CLI stores credentials at `~/.config/blodemd/credentials.json` (or `%APPDATA%\blodemd\` on Windows). `blodemd logout` removes that file. If the CLI finds no credentials file, it prints a message and exits cleanly. This command has no flags. ## Examples ```bash title="Log out" blodemd logout ``` ### Output ```bash $ blodemd logout ~ Logged out successfully. i Done ``` ```bash $ blodemd logout i No credentials found. ``` # blodemd new (https://docs.blode.md/cli/new) Create a new blode.md documentation site. Create a starter documentation directory with a `docs.json` configuration file and an `index.mdx` page. ```bash blodemd new [directory] ``` Interactive `blodemd new` inspects the current directory first: - If the current directory is empty, it scaffolds there and prompts for the project slug. - If the current directory is not empty, it asks whether to create the docs in a subdirectory or scaffold the current directory. - If prompts are skipped with `--yes` or in a non-interactive environment, it falls back to `docs/`. ## What it creates If you create the docs in a `docs/` subdirectory, `blodemd new` generates the following file tree: - docs/ - docs.json - index.mdx ### docs.json The generated configuration uses the hosted Blode.md schema and a single "Getting Started" navigation group. The `slug` field comes from the slug prompt, `--slug`, or a derived default. The `name` field defaults to a title-cased display name based on that slug unless you pass `--display-name`. ```json title="docs/docs.json" { "$schema": "https://blode.md/docs.json", "name": "My Project", "slug": "my-project", "navigation": { "groups": [ { "group": "Getting Started", "pages": ["index"] } ] } } ``` ### index.mdx A minimal starter page with a title and placeholder content: ```mdx title="docs/index.mdx" --- title: Welcome --- Start writing your docs here. ``` ## Starter template Use the starter template when you want a richer first pass with repo hygiene files, agent instructions, and branding assets: - `.gitignore` - `favicon.svg` - `README.md` - `AGENTS.md` - `CLAUDE.md` - `logo/light.svg` and `logo/dark.svg` - `images/hero-light.svg`, `images/hero-dark.svg`, and `images/checks-passed.svg` - `quickstart.mdx` - `development.mdx` ```bash title="Starter template" blodemd new --template starter ``` `AGENTS.md` links to `CLAUDE.md` when the local filesystem supports symlinks. The default `blodemd new` output stays as the minimal two-file scaffold. > [!INFO] > The starter does not generate a `LICENSE` file. Choose a license explicitly if > the repo will be public or open source. ## Options - `--slug ` (type: string): Project slug written to docs.json. If omitted, interactive mode prompts and non-interactive mode derives it from the chosen location. - `--name ` (type: string): Deprecated alias for `--slug`. - `--display-name ` (type: string): Display name written to docs.json `name`. Defaults to a title-cased version of the slug. - `--template ` (type: string, default: "minimal"): Scaffold an alternate template. Use "starter" for repo hygiene, helper files, and branding assets. - `--yes` (type: boolean, default: false): Accept defaults without prompting. ## Examples ```bash title="Default directory" blodemd new ``` ```bash title="Create docs/ explicitly" blodemd new docs ``` ```bash title="Scaffold the current directory" blodemd new . ``` ```bash title="Set the slug explicitly" blodemd new --slug acme-docs ``` ```bash title="Set slug and display name" blodemd new --slug docs --display-name "Blode.md" ``` ```bash title="Custom directory" blodemd new my-docs ``` ```bash title="Starter template" blodemd new --template starter ``` > [!INFO] > `blodemd new` stops with an error if the target directory already contains any > scaffolded files. It also refuses to scaffold into a non-empty directory > unless you confirm that interactively. ## Next steps 1. Review `docs.json` and change `slug` if you want a different deployment target or `{slug}.blode.md` subdomain. Change `name` if you want a different visible site title. 2. If you used the starter template, replace the generated helper files and brand assets with project-specific content. 3. Add more `.mdx` pages and update the `navigation` array. 4. Run `blodemd push` to deploy. # CLI overview (https://docs.blode.md/cli/overview) Install and use the blodemd command-line interface. The blodemd CLI lets you authenticate, create, validate, preview, and deploy documentation from your terminal. ## Installation ```bash npm i -g blodemd ``` Requires Node.js 24.x. The current version is **0.0.8**. ## Commands - `login` (type: command): Authenticate with Blode.md via GitHub in your browser. - `logout` (type: command): Remove stored credentials from your machine. - `whoami` (type: command): Show the current authentication status. - `new` (type: command): Create a new documentation site with a starter docs.json and index page. - `validate` (type: command): Validate your docs.json configuration file against the schema. - `push` (type: command): Deploy documentation to Blode.md. - `dev` (type: command): Start a local development server for real-time preview. ## Command reference ### [blodemd login](https://docs.blode.md/cli/login) Sign in with GitHub in your browser. ### [blodemd new](https://docs.blode.md/cli/new) Create a docs directory with starter files. ### [blodemd push](https://docs.blode.md/cli/push) Deploy your documentation to Blode.md. ### [blodemd dev](https://docs.blode.md/cli/dev) Run a local dev server with live reload. ### [blodemd validate](https://docs.blode.md/cli/validate) Validate your docs.json before deploying. ## Global behavior ### Credentials The CLI stores all authentication state at `~/.config/blodemd/credentials.json` and never sends credentials to any third party. ### Environment variables You can configure the CLI with environment variables instead of flags. - `BLODEMD_API_URL` (type: string, default: https://api.blode.md): Override the API base URL. - `BLODEMD_PROJECT` (type: string): Project slug. Overrides docs.json `slug`. - `BLODEMD_BRANCH` (type: string): Git branch name for the deployment. - `BLODEMD_COMMIT_MESSAGE` (type: string): Commit message attached to the deployment. # blodemd push (https://docs.blode.md/cli/push) Deploy documentation to Blode.md. Upload your documentation files and publish them to Blode.md in a single command. ```bash blodemd push [dir] ``` Authenticate once with `blodemd login` first. The CLI uses your browser GitHub session — no API keys. ## Directory resolution If you omit the `dir` argument, the CLI searches for a `docs.json` file in these locations (in order): 1. The current working directory 2. `./docs` 3. `./apps/docs` If none contain a `docs.json`, the current directory is used. ## Options - `--project ` (type: string): Project slug. Falls back to the BLODEMD_PROJECT environment variable, then docs.json `slug`. - `--api-url ` (type: string, default: "https://api.blode.md"): API base URL. - `--branch ` (type: string, default: "main"): Git branch name attached to the deployment. Auto-detected from git if not provided. - `--message ` (type: string): Deploy message. Auto-detected from the latest git commit if not provided. ## Deployment flow When you run `blodemd push`, the CLI executes these steps: 1. **Validate configuration** Reads and parses `docs.json` from the resolved docs directory. 1. **Collect files** Recursively collects all files in the directory. Dotfiles and `node_modules` are skipped automatically. 1. **Create deployment** Sends a request to the Blode.md API to create a new deployment record with the branch and commit message. 1. **Upload files** Uploads files in batches of up to 4 MB each. Large documentation sets are split across multiple requests. 1. **Finalize and promote** The CLI marks the deployment as complete and promotes it to production. Your docs are live immediately. ## Auto-create projects If the project slug does not match an existing project, the CLI prompts you to create one using your authenticated GitHub session. ## Examples ```bash title="Push from default location" blodemd push ``` ```bash title="Push a specific directory" blodemd push ./my-docs ``` ```bash title="Push with explicit project and branch" blodemd push --project my-project --branch staging ``` ## Zero-touch deploys Prefer not to run the CLI at all? Install the **Blode.md GitHub App** from the project Git tab in the dashboard. Pushes to your configured branch deploy automatically — no CLI, no tokens, no workflows. ## Skipped files The CLI skips the following entries during file collection: - Files and directories starting with `.` (dotfiles) - The `node_modules` directory # blodemd validate (https://docs.blode.md/cli/validate) Validate your docs.json configuration file. Check that your `docs.json` file is valid JSON and can be parsed by the CLI before deploying. ```bash blodemd validate [dir] ``` ## Directory resolution If you omit the `dir` argument, the CLI searches for `docs.json` in these locations (in order): 1. The current working directory 2. `./docs` 3. `./apps/docs` ## Options ## Examples ```bash title="Validate from default location" blodemd validate ``` ```bash title="Validate a specific directory" blodemd validate ./my-docs ``` ### Successful output ```bash $ blodemd validate ~ docs.json is valid. i Done ``` > [!INFO] > Running `blodemd push` also validates `docs.json` as its first step. A > standalone validate step is useful when you want to fail fast without needing > authentication. # blodemd whoami (https://docs.blode.md/cli/whoami) Show the currently authenticated user. Print the email of the active browser session. ```bash blodemd whoami ``` The CLI reads your stored OAuth session, refreshes it if needed, and displays your email. If your session has expired and can't be refreshed, the CLI prints a warning and asks you to run `blodemd login` again. This command has no flags. ## Examples ```bash $ blodemd whoami ~ Logged in as you@example.com i Done ``` # Accordion (https://docs.blode.md/components/accordion) Collapsible content sections for FAQs and detailed information. Use the `Accordion` component to hide content behind a toggle. Group multiple accordions together with `AccordionGroup` for a clean, bordered container. ## Basic accordion ```mdx Blode.md uses MDX, which combines standard Markdown with JSX components. You can also reference OpenAPI specs for auto-generated API docs. ``` ### What formats does blodemd support? Blode.md uses MDX, which combines standard Markdown with JSX components. You can also reference OpenAPI specs for auto-generated API docs. ## Accordion group Wrap multiple accordions in an `AccordionGroup` to render them in a single bordered container with dividers: ```mdx Run `blodemd new` in your project directory, then `blodemd dev` to preview locally. Yes. After deploying, add a custom domain in your project settings and update your DNS records. Blode.md offers a generous free tier for open-source and personal projects. ``` ### How do I get started? Run `blodemd new` in your project directory, then `blodemd dev` to preview locally. ### Can I use custom domains? Yes. After deploying, add a custom domain in your project settings and update your DNS records. ### Is there a free tier? Blode.md offers a generous free tier for open-source and personal projects. ## Default open Set `defaultOpen` to expand an accordion on page load: ```mdx You can use this for content that should be visible immediately but still collapsible. ``` ### This section is open by default You can use this for content that should be visible immediately but still collapsible. ## With a description Add a `description` prop to display secondary text below the title: ```mdx Run `blodemd push` to deploy your documentation. Changes go live in seconds. ``` ### Deployment Run `blodemd push` to deploy your documentation. Changes go live in seconds. ## Props ### Accordion - `title` (type: string, required: true): The heading text shown in the toggle button. - `description` (type: string, required: false): Secondary text displayed below the title. - `defaultOpen` (type: boolean, required: false, default: false): Whether the accordion starts expanded. - `id` (type: string, required: false): Custom anchor ID. Defaults to a slugified version of the title. - `icon` (type: ReactNode, required: false): Icon displayed before the title. - `children` (type: ReactNode, required: true): Content revealed when the accordion is open. ### AccordionGroup `AccordionGroup` accepts `children` (one or more `Accordion` components) and renders them in a bordered container. # Callout (https://docs.blode.md/components/callout) Highlight important information with colored alert boxes. Use the `Callout` component to draw attention to important information. Each callout type has a distinct color to signal its intent. ## Basic usage Wrap your content in a `` with a `type` prop: ```mdx This is an informational callout. ``` > [!INFO] > This is an informational callout. ## Types There are seven built-in callout types: > [!NOTE] > Use **note** for general-purpose annotations. > [!INFO] > Use **info** for supplemental context. > [!TIP] > Use **tip** for helpful suggestions and best practices. > [!CHECK] > Use **check** to confirm a successful outcome. > [!WARNING] > Use **warning** when something could cause issues. > [!DANGER] > Use **danger** for critical information about destructive actions. > [!SUCCESS] > Use **success** to highlight a positive result. ## Shorthand aliases Each callout type has a shorthand component that you can use without the `type` prop: ```mdx A concise note for your readers. This action cannot be undone. You can combine callouts with other components. ``` > [!NOTE] > A concise note for your readers. > [!WARNING] > This action cannot be undone. > [!INFO] > Shorthand aliases keep your MDX clean and readable. > [!TIP] > You can combine callouts with other components. > [!CHECK] > Your configuration is valid. > [!DANGER] > Deleting a project removes all associated data permanently. The available aliases are ``, ``, ``, ``, ``, and ``. ## With a title Add a `title` prop to display a heading above the callout content: ```mdx The `v2` API removes the `legacy` parameter. Update your integration before upgrading. ``` > [!WARNING] > The `v2` API removes the `legacy` parameter. Update your integration before > upgrading. ## Props - `type` (type: "info" | "success" | "warning" | "danger" | "note" | "tip" | "check", required: false, default: "info"): Visual style of the callout. - `title` (type: string, required: false): Optional heading displayed above the content. - `icon` (type: ReactNode, required: false): Custom icon rendered before the content. - `color` (type: string, required: false): Custom border and background color (hex or CSS color). - `children` (type: ReactNode, required: true): The callout content. # Card (https://docs.blode.md/components/card) Display content in a styled container with optional links and icons. Use the `Card` component to present content in a bordered container. Cards work well for feature highlights, navigation links, and content grids. ## Basic card ```mdx Learn how to set up your first documentation project. ``` ### Getting started Learn how to set up your first documentation project. ## Link card Add an `href` prop to make the entire card clickable. An arrow indicator appears automatically: ```mdx Set up a documentation site in under five minutes. ``` ### [Quickstart guide](https://docs.blode.md/quickstart) Set up a documentation site in under five minutes. ## Card with call to action Use the `cta` prop to display a text label at the bottom of the card: ```mdx Serve your docs from your own domain with automatic SSL. ``` ### [Custom domains](https://docs.blode.md/features/custom-domains) Serve your docs from your own domain with automatic SSL. ## Card grid Combine cards with `Columns` to create a responsive grid: ```mdx Commands for building and deploying docs. Customize your project settings. Write documentation with Markdown and JSX. Full-text search built into every project. ``` ### [CLI reference](https://docs.blode.md/cli/overview) Commands for building and deploying docs. ### [Configuration](https://docs.blode.md/configuration/docs-json) Customize your project settings. ### [MDX basics](https://docs.blode.md/content/mdx-basics) Write documentation with Markdown and JSX. ### [Search](https://docs.blode.md/features/search) Full-text search built into every project. ## Horizontal layout Set `horizontal` to arrange the icon and content side by side: ```mdx Content flows beside the icon in a horizontal layout. ``` ### Horizontal card Content flows beside the icon in a horizontal layout. ## Props - `title` (type: string, required: false): Heading displayed at the top of the card. - `icon` (type: ReactNode, required: false): Icon rendered above the title. - `color` (type: string, required: false): Custom color for the icon. - `href` (type: string, required: false): URL that makes the card clickable. External links open in a new tab. - `horizontal` (type: boolean, required: false): Arrange icon and content side by side. - `img` (type: string, required: false): Image URL displayed at the top of the card. - `cta` (type: string, required: false): Call-to-action text displayed at the bottom. - `children` (type: ReactNode, required: false): Card body content. # Code group (https://docs.blode.md/components/code-group) Display multiple code blocks with tabbed navigation. Use the `CodeGroup` component to show multiple related code blocks in a single tabbed container. This is useful for showing the same command or snippet across different languages or tools. ## Basic usage Wrap two or more fenced code blocks inside ``. Each tab is labeled from the `title` attribute on the code block: ```text ```bash title="npm" npm install blodemd ``` ```bash title="pnpm" pnpm add blodemd ``` ```bash title="yarn" yarn add blodemd ``` ``` ```bash title="npm" npm install blodemd ``` ```bash title="pnpm" pnpm add blodemd ``` ```bash title="yarn" yarn add blodemd ``` ## Multi-language example Show the same API call in different programming languages: ```text ```javascript title="Node.js" const res = await fetch("https://api.blode.md/v1/projects", { headers: { Authorization: `Bearer ${API_KEY}` }, }); const data = await res.json(); ``` ```python title="Python" import requests res = requests.get( "https://api.blode.md/v1/projects", headers={"Authorization": f"Bearer {API_KEY}"}, ) data = res.json() ``` ```bash title="cURL" curl -H "Authorization: Bearer $API_KEY" \ https://api.blode.md/v1/projects ``` ``` ```javascript title="Node.js" const res = await fetch("https://api.blode.md/v1/projects", { headers: { Authorization: `Bearer ${API_KEY}` }, }); const data = await res.json(); ``` ```python title="Python" import requests res = requests.get( "https://api.blode.md/v1/projects", headers={"Authorization": f"Bearer {API_KEY}"}, ) data = res.json() ``` ```bash title="cURL" curl -H "Authorization: Bearer $API_KEY" \ https://api.blode.md/v1/projects ``` ## Tab labels Tabs are labeled in this order of priority: 1. The `title` attribute on the code fence, such as ```bash title="npm" 2. The language identifier (e.g., `javascript`, `python`) 3. A generic fallback like "Tab 1" > [!TIP] > Always set explicit `title` attributes when the language alone does not > distinguish the tabs. # Columns (https://docs.blode.md/components/columns) Arrange content in multi-column layouts. Use the `Columns` component to create responsive grid layouts. Columns stack on small screens and expand on larger viewports. ## Two-column layout The default `cols` value is `2`: ```mdx Use standard Markdown with built-in components. Push your changes and go live in seconds. ``` ### Write in MDX Use standard Markdown with built-in components. ### Deploy instantly Push your changes and go live in seconds. ## Three-column layout Set `cols={3}` for a three-column grid: ```mdx Build and deploy from your terminal. Rich UI elements for your content. Full-text search out of the box. ``` ### [CLI](https://docs.blode.md/cli/overview) Build and deploy from your terminal. ### [Components](https://docs.blode.md/components/callout) Rich UI elements for your content. ### [Search](https://docs.blode.md/features/search) Full-text search out of the box. ## With Column wrapper Use the `Column` component when you need to place non-card content in the grid: ```mdx ### Left side You can put any Markdown or components in a column. ### Right side Columns are useful for side-by-side comparisons. ``` ### Left side You can put any Markdown or components in a column. ### Right side Columns are useful for side-by-side comparisons. ## Props ### Columns - `cols` (type: 1 | 2 | 3 | 4, required: false, default: 2): Number of columns in the grid. - `children` (type: ReactNode, required: true): Grid content (cards, Column components, or other elements). ### Column `Column` accepts `children` and renders them inside a single grid cell. # Expandable (https://docs.blode.md/components/expandable) Collapsible sections for nested property details. Use the `Expandable` component to hide supplementary details behind a toggle. This is useful for documenting nested objects, optional configuration, or advanced options without overwhelming the reader. ## Basic usage ```mdx - **name** (`string`) — Display name of the item. - **value** (`number`) — Numeric value associated with the item. - **metadata** (`object`) — Additional key-value pairs. ``` ### child properties - **name** (`string`) — Display name of the item. - **value** (`number`) — Numeric value associated with the item. - **metadata** (`object`) — Additional key-value pairs. ## Default open Set `defaultOpen` to reveal the content on page load: ```mdx - **id** (`string`) — Unique identifier. - **status** (`"active" | "archived"`) — Current status. - **createdAt** (`string`) — ISO 8601 timestamp. ``` ### response fields - **id** (`string`) — Unique identifier. - **status** (`"active" | "archived"`) — Current status. - **createdAt** (`string`) — ISO 8601 timestamp. ## Nested expandables You can nest expandables to document deeply nested structures: ```mdx - **name** (`string`) — Project name. - **config** (`object`) — Project configuration. - **appearance** (`object`) — Light and dark mode settings. - **navigation** (`array`) — Sidebar navigation items. ``` ### project properties - **name** (`string`) — Project name. - **config** (`object`) — Project configuration. ### config properties - **appearance** (`object`) — Light and dark mode settings. - **navigation** (`array`) — Sidebar navigation items. ## Props - `title` (type: string, required: false, default: "properties"): Label for the toggle button. - `defaultOpen` (type: boolean, required: false, default: false): Whether the section starts expanded. - `children` (type: ReactNode, required: true): Content revealed when expanded. # Frame (https://docs.blode.md/components/frame) Wrap content in a bordered container with an optional caption. Use the `Frame` component to visually set apart screenshots, diagrams, or other media with a bordered container and an optional caption. ## Basic frame ```mdx ![Dashboard overview](https://docs.blode.md/images/dashboard.png) ``` ## With a caption Add a `caption` prop to display centered text below the frame: ```mdx ![Dashboard overview](https://docs.blode.md/images/dashboard.png) ``` A placeholder for a screenshot or diagram. Caption: The project dashboard shows recent deployments and page analytics. ## With a hint Use the `hint` prop to display helper text above the frame: ```mdx ![Navigation config](https://docs.blode.md/images/nav-config.png) ``` Click to enlarge A placeholder for a screenshot or diagram. Caption: Navigation configuration in docs.json ## Props - `caption` (type: string, required: false): Text displayed below the frame as a figcaption. - `hint` (type: string, required: false): Helper text displayed above the frame. - `children` (type: ReactNode, required: true): Content rendered inside the bordered container. # Installer (https://docs.blode.md/components/installer) Display a styled package installation command. Use the `Installer` component to show a copyable installation command in a styled container. ## Basic usage Pass a `command` prop with the full install command: ```mdx ``` ```bash npm install blodemd ``` ## Default command If you omit the `command` prop, a default command is generated from the `path` value: ```mdx ``` ## Props - `path` (type: string, required: true): Package path used to generate the default command. - `command` (type: string, required: false): Custom install command. Overrides the default generated from `path`. # Steps (https://docs.blode.md/components/steps) Display numbered step-by-step instructions. Use the `Steps` and `Step` components to present sequential instructions. Each step is automatically numbered. ## Basic usage ```text Run the install command for your package manager: ```bash npm i -g blodemd ``` Create a new docs project in the current directory: ```bash blodemd new ``` Preview your documentation locally: ```bash blodemd dev ``` ``` 1. **Install the CLI** Run the install command for your package manager: ```bash npm i -g blodemd ``` 1. **Create your project** Create a new docs project in the current directory: ```bash blodemd new ``` 1. **Start the dev server** Preview your documentation locally: ```bash blodemd dev ``` ## Title sizing Control the heading level of step titles with `titleSize`, either on individual steps or on the parent `Steps` component: ```mdx Edit `docs.json` to set your project name and navigation. Create MDX files in the `docs/` directory. ``` 1. **Configure your project** Edit `docs.json` to set your project name and navigation. 1. **Write your content** Create MDX files in the `docs/` directory. ## Props ### Steps - `titleSize` (type: "p" | "h2" | "h3" | "h4", required: false, default: "p"): Default heading level for all child steps. - `children` (type: ReactNode, required: true): One or more Step components. ### Step - `title` (type: string, required: true): The step heading text. - `icon` (type: ReactNode, required: false): Custom icon to replace the step number. - `stepNumber` (type: number, required: false): Override the automatic step number. - `titleSize` (type: "p" | "h2" | "h3" | "h4", required: false, default: "p"): Heading level for this step. Overrides the parent value. - `children` (type: ReactNode, required: false): Content displayed below the step title. # Tabs (https://docs.blode.md/components/tabs) Organize content into switchable tabbed panels. Use the `Tabs` and `Tab` components to let readers switch between related content without leaving the page. ## Basic tabs Each `Tab` needs a `title` prop to label its tab button: ```text `npm install blodemd` `pnpm add blodemd` `yarn add blodemd` ``` ### npm `npm install blodemd` ### pnpm `pnpm add blodemd` ### yarn `yarn add blodemd` ## Content tabs Tabs work with any content, not just code: ```mdx Blode.md turns your Markdown files into a production-ready documentation site. - Full-text search - Custom domains - OpenAPI integration - Built-in components ``` ### Overview Blode.md turns your Markdown files into a production-ready documentation site. ### Features - Full-text search - Custom domains - OpenAPI integration - Built-in components ## Default tab Use `defaultTabIndex` on `Tabs` to set which tab is active on load (zero-indexed): ```mdx This tab is not selected by default. This tab is selected by default. ``` ### First This tab is not selected by default. ### Second This tab is selected by default. ## Props ### Tabs - `defaultTabIndex` (type: number, required: false, default: 0): Index of the tab to show on initial render. - `children` (type: ReactNode, required: true): One or more Tab components. ### Tab - `title` (type: string, required: false): Label displayed on the tab button. You can also use `label` as an alias. - `icon` (type: ReactNode, required: false): Icon displayed before the tab label. - `children` (type: ReactNode, required: true): Content shown when the tab is active. # Tree (https://docs.blode.md/components/tree) Display interactive file and directory structures. Use the `Tree` component to visualize file and folder hierarchies. Folders are collapsible by default, giving readers an interactive way to explore project structures. ## Basic usage ```mdx ``` - docs/ - index.mdx - quickstart.mdx - components/ - callout.mdx - card.mdx - tabs.mdx - docs.json - package.json ## Collapsed by default Omit `defaultOpen` to keep folders collapsed. Readers can click to expand them: ```mdx ``` - src/ - components/ - header.tsx - footer.tsx - lib/ - utils.ts - index.ts ## Non-openable folders Set `openable={false}` to display a folder that cannot be expanded, useful for indicating a directory without listing its contents: ```mdx ``` - public/ - src/ - app.tsx - node_modules/ ## Props ### Tree `Tree` renders a bordered container for the file hierarchy. It accepts `children`. ### Tree.Folder - `name` (type: string, required: true): Folder name displayed in the tree. - `defaultOpen` (type: boolean, required: false, default: false): Whether the folder starts expanded. - `openable` (type: boolean, required: false, default: true): Whether the folder can be toggled open and closed. - `children` (type: ReactNode, required: false): Nested files and folders. ### Tree.File - `name` (type: string, required: true): File name displayed in the tree. # Type table (https://docs.blode.md/components/type-table) Display structured property and type reference tables. Use the `TypeTable` component to document object shapes, API responses, and component props in a structured table. ## Basic usage Pass a `type` object where each key is a field name and the value describes its type, description, and constraints: ```mdx ``` - `id` (type: string, required: true): Unique project identifier. - `name` (type: string, required: true): Display name of the project. - `slug` (type: string, required: true): URL-safe project slug. - `customDomain` (type: string, required: false): Custom domain if configured. - `createdAt` (type: string, required: true): ISO 8601 timestamp of project creation. ## With default values When any field includes a `default` property, a Default column appears automatically: ```mdx ``` - `appearance` (type: "system" | "light" | "dark", required: false, default: "system"): Initial color mode for the site. - `lang` (type: string, required: false, default: "plaintext"): Default language for code blocks. - `toc` (type: boolean, required: false, default: true): Show a table of contents on each page. ## Field options Each field in the `type` object supports these properties: - `description` (type: string, required: false): Human-readable explanation of the field. - `type` (type: string, required: false): The field's type annotation. - `required` (type: boolean, required: false): Whether the field is required. Defaults to the inverse of `optional`. - `optional` (type: boolean, required: false): Whether the field is optional. Inverse of `required`. - `default` (type: string, required: false): Default value shown in the table. # docs.json reference (https://docs.blode.md/configuration/docs-json) Configure navigation, branding, and runtime behavior with docs.json. Every Blode.md project is configured through a single `docs.json` file at the root of your docs directory. > [!INFO] > If you are coming from Mintlify, Blode.md intentionally keeps this contract > smaller. `theme`, `colors`, `fonts`, `icons`, `background`, and `styling` are > not supported in `docs.json`. ## Minimal example ```json title="docs.json" { "$schema": "https://blode.md/docs.json", "name": "My Project", "slug": "my-project", "navigation": { "groups": [{ "group": "Getting started", "pages": ["index"] }] } } ``` ## Branded example ```json title="docs.json" { "$schema": "https://blode.md/docs.json", "name": "My Project", "slug": "my-project", "description": "Documentation for my product.", "logo": { "light": "/logo/light.svg", "dark": "/logo/dark.svg", "alt": "Example Co. logo", "href": "/" }, "favicon": "/favicon.svg", "appearance": { "default": "system" }, "navbar": { "links": [{ "label": "GitHub", "href": "`github.com/example/docs`" }] }, "navigation": { "tabs": [ { "tab": "Guides", "groups": [ { "group": "Getting started", "pages": ["index", "quickstart"] } ] } ] }, "contextual": { "options": ["copy", "view", "chatgpt", "claude"] }, "api": { "openapi": "openapi.yaml", "playground": { "display": "interactive" } }, "seo": { "indexing": "all" } } ``` ## Top-level fields - `$schema` (type: string): JSON Schema URL for editor autocomplete. Use `https://blode.md/docs.json`. - `name` (type: string, required: true): Display name for your site, project, or organization. - `slug` (type: string): Recommended URL-safe project slug used for deployments and the default `{slug}.blode.md` hostname. - `description` (type: string): Short project description used in metadata and SEO. - `logo` (type: string | { light, dark, alt?, href? }): Logo shown in the header. Accepts a single path or `{ light, dark, alt?, href? }`. - `favicon` (type: string | { light, dark }): Browser tab icon. Accepts a single path or `{ light, dark }`. - `appearance` (type: object): Light and dark mode settings. Set `default` to `dark`, `light`, or `system`. Use `strict` to lock the site mode. - `navbar` (type: object): Header links shown above your content. - `navigation` (type: object, required: true): Sidebar and tab structure. Defines the hierarchy of your pages. See [Navigation](https://docs.blode.md/configuration/navigation). - `api` (type: object): API reference configuration for OpenAPI and AsyncAPI sources plus playground settings. - `contextual` (type: object): Contextual action buttons shown on each page, such as copy, view source, or assistant shortcuts. - `search` (type: object): Search configuration. - `seo` (type: object): Search engine indexing settings. - `metadata` (type: object): Metadata configuration. ## Branding fields - `logo.light` (type: string): Logo path for light mode. - `logo.dark` (type: string): Logo path for dark mode. - `logo.alt` (type: string): Accessible alt text for the logo image. - `logo.href` (type: string): Optional destination when someone clicks the logo. Defaults to the docs homepage. - `favicon.light` (type: string): Favicon path for light mode. - `favicon.dark` (type: string): Favicon path for dark mode. - `appearance.default` (type: 'system' | 'light' | 'dark'): Initial color mode. Defaults to `system`. - `appearance.strict` (type: boolean): When `true`, hides the mode toggle and locks the site to the selected default mode. ## API reference The `api` object controls OpenAPI and AsyncAPI rendering plus playground behavior. - `api.openapi` (type: string | string[] | OpenApiSource): Path to your OpenAPI spec. Accepts a string, array of strings, or a source object with `source`, `basePath`, `directory`, and `include`. - `api.asyncapi` (type: string | string[] | OpenApiSource): Path to your AsyncAPI spec. Same format as `openapi`. - `api.playground` (type: { display?: 'auth' | 'interactive' | 'none' | 'simple', proxy?: boolean, credentials?: boolean }): API playground settings. - `api.examples` (type: { autogenerate?: boolean, defaults?: 'all' | 'required', languages?: string[], prefill?: boolean }): Autogenerated code example settings. - `api.params` (type: { expanded?: 'all' | 'closed' }): Parameter display settings. - `api.mdx` (type: { auth?: { method, name }, server?: string | string[] }): MDX API page settings. - `api.url` (type: 'full'): URL display mode for endpoint headers. ## Contextual actions - `contextual.display` (type: 'header' | 'toc'): Where to render the action buttons. - `contextual.options` (type: Array): Array of built-in presets or custom action objects. Built-in option presets: `copy`, `view`, `chatgpt`, `claude`, `perplexity`, `grok`, `aistudio`, `cursor`, `vscode`, `windsurf`, `devin`, `mcp`, `add-mcp`, `devin-mcp`, `assistant`. ## Validation Run `blodemd validate` to check your `docs.json` against the schema before deploying: ```bash blodemd validate ``` ## Related pages - [Navigation](https://docs.blode.md/configuration/navigation) -- configure sidebar groups, tabs, and page ordering - [Appearance and branding](https://docs.blode.md/configuration/theming) -- configure logo, favicon, and color mode behavior # Navigation (https://docs.blode.md/configuration/navigation) Configure sidebar groups, tabs, and page ordering in docs.json. You control the sidebar hierarchy, tabbed sections, and hidden pages through the `navigation` object in `docs.json`. This page covers every navigation feature. ## Groups Groups organize pages into collapsible sidebar sections. Each group has a label and a list of page slugs. ```json title="docs.json" { "navigation": { "groups": [ { "group": "Getting started", "pages": ["index", "quickstart"] }, { "group": "Guides", "pages": ["guides/authentication", "guides/deployment"] } ] } } ``` - `group` (type: string): Display label for the sidebar section. - `pages` (type: string[]): Array of page slugs. Each slug maps to an MDX file relative to your docs root. - `expanded` (type: boolean): Whether the group is expanded by default. Defaults to `true` for the first group. - `hidden` (type: boolean): Hide this group from the sidebar while keeping its pages accessible by URL. ### Directory paths Page slugs map directly to file paths. A slug like `domains/custom-domains` resolves to `domains/custom-domains.mdx` in your docs directory. ``` docs/ domains/ custom-domains.mdx -> slug: "domains/custom-domains" ssl.mdx -> slug: "domains/ssl" index.mdx -> slug: "index" ``` ## Tabs Tabs add top-level sections to your documentation. Each tab contains its own set of groups, creating separate sidebar navigations. ```json title="docs.json" { "navigation": { "tabs": [ { "tab": "Guides", "groups": [ { "group": "Getting started", "pages": ["index", "quickstart"] } ] }, { "tab": "API reference", "groups": [ { "group": "Endpoints", "pages": ["api/users", "api/projects"] } ] }, { "tab": "Changelog", "href": "/changelog" } ] } } ``` - `tab` (type: string, required: true): Display label for the tab. This is the `label` field in the schema. - `groups` (type: Array): Array of sidebar groups displayed when this tab is active. - `pages` (type: string[]): Flat list of page slugs (alternative to groups for simple tabs). - `href` (type: string): External URL. When set, clicking the tab navigates away instead of showing a sidebar. - `icon` (type: string): Icon name displayed next to the tab label. > [!INFO] > A tab must define at least one of `groups`, `pages`, or `href`. ## Hidden pages Use the `hidden` array to keep pages accessible by URL without showing them in the sidebar. This is useful for deprecated pages, redirects, or unlisted content. ```json title="docs.json" { "navigation": { "hidden": ["internal/debug", "legacy/old-api"], "groups": [{ "group": "Guides", "pages": ["index", "quickstart"] }] } } ``` ## OpenAPI auto-generated pages You can generate API reference pages directly from an OpenAPI spec by adding an `openapi` field to a group instead of listing pages manually. ```json title="String source" { "group": "API reference", "openapi": "openapi.yaml" } ``` ```json title="Object source" { "group": "API reference", "openapi": { "source": "openapi.yaml", "basePath": "/api", "directory": "api-ref", "include": ["GET /users", "POST /users"] } } ``` - `source` (type: string, required: true): Path to your OpenAPI spec file. - `basePath` (type: string): Base path prefix for generated page slugs. - `directory` (type: string): Output directory for generated MDX files. - `include` (type: string[]): Filter to specific operations (e.g., `GET /users`). ## Splitting navigation with $ref For large projects, you can split your navigation into separate JSON files using `$ref`. This keeps your main `docs.json` manageable. ```json title="docs.json" { "navigation": { "tabs": [{ "$ref": "./nav/guides.json" }, { "$ref": "./nav/api.json" }] } } ``` ```json title="nav/guides.json" { "tab": "Guides", "groups": [{ "group": "Getting started", "pages": ["index", "quickstart"] }] } ``` ## Versions Version dropdowns let you maintain multiple documentation versions from a single project. ```json title="docs.json" { "navigation": { "versions": [ { "label": "v2.0", "url": "/v2" }, { "label": "v1.0", "url": "/v1" } ], "groups": [...] } } ``` - `label` (type: string, required: true): Version label displayed in the dropdown. - `url` (type: string, required: true): URL path or full URL for this version. ## Languages Language selectors let you link to translated versions of your documentation. ```json title="docs.json" { "navigation": { "languages": [ { "label": "English", "url": "/en" }, { "label": "Japanese", "url": "/ja", "locale": "ja" } ], "groups": [...] } } ``` - `label` (type: string, required: true): Language name displayed in the selector. - `url` (type: string, required: true): URL path or full URL for this language. - `locale` (type: string): BCP 47 locale code (e.g., `ja`, `fr`, `zh-CN`). ## Global anchors Global anchors appear as persistent links in the navigation, visible across all tabs. Use them for external resources like your dashboard, community, or changelog. ```json title="docs.json" { "navigation": { "global": { "anchors": [ { "label": "Community", "href": "/community" }, { "label": "Dashboard", "href": "/app" } ], "links": [ { "label": "Blog", "href": "/blog" } ] }, "groups": [...] } } ``` - `global.anchors` (type: Array<{ label: string, href: string }>): Persistent anchor links shown across all tabs. - `global.links` (type: Array<{ label: string, href: string }>): Additional navigation links shown globally. ## Complete navigation schema The full navigation object supports all of the following fields: - `tabs` (type: Array): Top-level tabbed sections. Each tab has its own sidebar. - `groups` (type: Array): Sidebar groups when not using tabs. - `pages` (type: string[]): Flat list of page slugs (simplest form, no grouping). - `hidden` (type: string[]): Page slugs accessible by URL but not shown in the sidebar. - `versions` (type: Array<{ label, url }>): Version dropdown entries. - `languages` (type: Array<{ label, url, locale? }>): Language selector entries. - `global` (type: { anchors?, links? }): Global anchors and links visible across all tabs. > [!INFO] > Your navigation must define at least one of `groups`, `pages`, `tabs`, > `languages`, or `versions`. # Appearance and branding (https://docs.blode.md/configuration/theming) Configure your logo, favicon, and light/dark mode behavior in docs.json. Blode.md keeps site branding intentionally narrow. Use `logo`, `favicon`, and `appearance` in `docs.json` to control the parts of the visual identity that are currently supported. The `logo` and `favicon` shapes follow Mintlify's light and dark asset pattern, and Blode.md also accepts `logo.alt` for accessible text. > [!INFO] > Blode.md does not support Mintlify's `theme`, `colors`, `fonts`, `icons`, > `background`, or `styling` fields. ## Logo Use `logo` to show a single mark everywhere or separate assets for light and dark mode. ### Tab ```json title="docs.json" { "logo": { "light": "/logo/light.svg", "dark": "/logo/dark.svg", "alt": "Example Co. logo", "href": "/" } } ``` ### Tab ```json title="docs.json" { "logo": "/logo/logo.svg" } ``` - `light` (type: string): Logo image path or URL for light mode. - `dark` (type: string): Logo image path or URL for dark mode. - `href` (type: string): Optional destination when someone clicks the logo. Defaults to your docs homepage. - `alt` (type: string): Accessible alt text for the logo image. ## Favicon Use `favicon` for the browser tab icon. ```json title="Single favicon" { "favicon": "/favicon.svg" } ``` ```json title="Light and dark variants" { "favicon": { "light": "/favicon-light.svg", "dark": "/favicon-dark.svg" } } ``` ## Appearance Use `appearance` to control the initial light or dark mode and whether readers can switch modes. ```json title="docs.json" { "appearance": { "default": "dark", "strict": true } } ``` - `default` (type: 'system' | 'light' | 'dark'): Default color mode. Choose `system`, `light`, or `dark`. - `strict` (type: boolean): When `true`, locks the site to the default mode and hides the theme toggle. ## Example ```json title="docs.json" { "$schema": "https://blode.md/docs.json", "name": "Example Docs", "slug": "example-docs", "logo": { "light": "/logo/light.svg", "dark": "/logo/dark.svg", "alt": "Example Co. logo", "href": "/" }, "favicon": "/favicon.svg", "appearance": { "default": "system" }, "navigation": { "groups": [{ "group": "Getting started", "pages": ["index"] }] } } ``` Blode.md uses its built-in visual system for layout, typography, and component styling. Branding today is about the assets and mode behavior you provide here, not per-site theme tokens. # Code blocks (https://docs.blode.md/content/code-blocks) Syntax highlighting, titles, and multi-file code examples. Fenced code blocks are automatically syntax-highlighted using Shiki with dual themes (light and dark). ## Basic usage Use triple backticks with a language identifier: ```text ```javascript const greeting = "Hello, world!"; console.log(greeting); ``` ``` ## Titles Add a filename or label with the `title` attribute: ```text ```typescript title="src/config.ts" export const config = { name: "my-project", version: "1.0.0", }; ``` ``` ## Supported languages Shiki supports over 300 languages, including: `javascript`, `typescript`, `python`, `go`, `rust`, `bash`, `json`, `yaml`, `mdx`, `sql`, `css`, `html`, and many more. ## Multi-file examples Use the `CodeGroup` component to show multiple related code blocks with tabbed navigation: ```text ```bash title="npm" npm install blodemd ``` ```bash title="pnpm" pnpm add blodemd ``` ```bash title="yarn" yarn add blodemd ``` ``` Tabs are automatically labeled from the `title` attribute. If no title is set, the language name is used. ## Inline code Use single backticks for inline code: `` `blodemd push` `` renders as `blodemd push`. # Frontmatter (https://docs.blode.md/content/frontmatter) All available YAML frontmatter fields for documentation pages. Every MDX page starts with YAML frontmatter between `---` delimiters. The `title` field is required. All other fields are optional. ## Fields - `title` (type: string, required: true): Page title displayed in the header and browser tab. - `description` (type: string): Summary used in meta tags and search results. - `sidebarTitle` (type: string): Override the title shown in the sidebar navigation. - `icon` (type: string): Icon displayed next to the page title in the sidebar. - `iconType` (type: "regular" | "solid" | "light" | "thin" | "sharp-solid" | "duotone" | "brands"): Icon style variant. - `mode` (type: "default" | "wide" | "custom" | "frame" | "center", default: "default"): Page layout mode. - `hidden` (type: boolean, default: false): Hide this page from navigation. The page is still accessible via direct URL. - `deprecated` (type: boolean, default: false): Mark the page as deprecated. Displays a deprecation badge. - `noindex` (type: boolean, default: false): Prevent search engines from indexing this page. - `keywords` (type: string[]): Additional keywords for search indexing. - `tag` (type: string): Display a tag badge next to the page title. - `url` (type: string): Override the navigation link to point to an external URL. - `hideApiMarker` (type: boolean): Hide the API method badge on OpenAPI pages. - `hideFooterPagination` (type: boolean): Hide the previous/next navigation at the bottom of the page. ## Example ```yaml --- title: Authentication description: Learn how to authenticate API requests. icon: lock tag: Updated mode: wide --- ``` # MDX basics (https://docs.blode.md/content/mdx-basics) Write documentation with Markdown and JSX components. MDX combines Markdown with JSX components. You write standard Markdown, and when you need richer elements, you use built-in components directly in your content. No imports are needed. ## Markdown All standard Markdown syntax works, including GitHub Flavored Markdown (GFM): - **Headings** — `#`, `##`, `###`, etc. - **Bold** and _italic_ text - Lists (ordered and unordered) - [Links](https://blode.md) and images - Blockquotes - Tables - Fenced code blocks with syntax highlighting ## Using components Blode.md provides over 30 built-in components. Use them directly in your MDX without any import statements: ```mdx This is a paragraph with standard Markdown. This is a callout component rendered inline. ``` Components accept props just like JSX: ```mdx Card content goes here. ``` ## Frontmatter Every page starts with YAML frontmatter between `---` delimiters: ```mdx --- title: My page title description: A brief summary of this page. --- Page content starts here. ``` The `title` field is required. See the [frontmatter reference](https://docs.blode.md/content/frontmatter) for all available fields. ## File naming Pages are referenced by their file path without the `.mdx` extension. A file at `getting-started/installation.mdx` is referenced as `"getting-started/installation"` in your navigation config. > [!NOTE] > File names become URL slugs. Use lowercase with hyphens: `my-page.mdx`, not > `My Page.mdx`. ## Component reference Browse all available components in the [Components](https://docs.blode.md/components/callout) tab. # Deploying with push (https://docs.blode.md/deployment/push) Deploy your documentation to Blode.md with a single command. You deploy documentation to Blode.md by running `blodemd push`. This page covers the command options, how directory resolution works, and what happens during a deployment. ## Command ```bash blodemd push [dir] ``` The optional `dir` argument specifies the path to your docs directory. If omitted, the CLI searches for `docs.json` automatically. ## Options - `--project ` (type: string): Project slug. Overrides docs.json `slug`. Can also be set with `BLODEMD_PROJECT`. If `slug` is missing, the CLI temporarily falls back to docs.json `name` for backward compatibility. - `--api-key ` (type: string): API key for authentication. Overrides stored credentials. Can also be set with `BLODEMD_API_KEY`. - `--api-url ` (type: string, default: https://api.blode.md): API base URL. Can also be set with `BLODEMD_API_URL`. - `--branch ` (type: string): Git branch name attached to the deployment. Can also be set with `BLODEMD_BRANCH`. - `--message ` (type: string): Deploy message. Can also be set with `BLODEMD_COMMIT_MESSAGE`. ## Directory resolution When you omit the `dir` argument, the CLI checks for `docs.json` in this order: 1. Current working directory (`./`) 2. `./docs/` 3. `./apps/docs/` If none of these contain a `docs.json`, the CLI defaults to the current directory. > [!INFO] > If you pass an explicit directory (e.g., `blodemd push my-docs`), the CLI uses > that path directly without searching. ## What happens during a push When you run `blodemd push`, the CLI performs these steps: 1. **Validate configuration** The CLI reads and parses `docs.json` from the resolved directory. If the file is missing or invalid, the push fails immediately. 1. **Resolve credentials** Authentication is resolved in this order: `--api-key` flag, `BLODEMD_API_KEY` environment variable, stored credentials from `blodemd login`. 1. **Collect files** The CLI walks the docs directory recursively, skipping dotfiles (files and directories starting with `.`) and `node_modules`. The file list is sorted alphabetically. 1. **Create deployment** A new deployment record is created on the server with the resolved branch name and commit message. 1. **Upload files** Files are base64-encoded and uploaded in batches. Each batch stays under 4 MB to work within serverless payload limits. The CLI shows progress as batches complete. 1. **Finalize deployment** The deployment is finalized and promoted to live. Your docs are available immediately at `your-slug.blode.md`. ## Project auto-creation If the project slug does not exist on Blode.md, the CLI offers to create it for you. This only works when you are logged in with browser OAuth (via `blodemd login`). API key authentication cannot auto-create projects. When a project is created, the CLI prints an API key for use in CI/CD pipelines. Save this key -- it is only displayed once. ``` Project my-project created API key for CI: bmd_abc123... ``` ## File handling The CLI applies these rules when collecting files: - **Skipped entries**: any file or directory starting with `.` (e.g., `.git`, `.env`) and `node_modules` - **All other files**: included regardless of extension (MDX, JSON, images, fonts, etc.) - **Batch size**: files are uploaded in batches of up to 4 MB each - **Content types**: text files (MDX, JSON, YAML, CSS, JS, HTML, SVG) are uploaded with their correct MIME type; all others use `application/octet-stream` ## Branch resolution The branch name is resolved in this order: 1. `--branch` flag 2. `BLODEMD_BRANCH` environment variable 3. `GITHUB_REF_NAME` environment variable (auto-set by GitHub Actions) 4. Current git branch (`git rev-parse --abbrev-ref HEAD`) 5. Falls back to `main` ## Commit message resolution The commit message is resolved in this order: 1. `--message` flag 2. `BLODEMD_COMMIT_MESSAGE` environment variable 3. Latest git commit message (`git log -1 --pretty=%s`) ## Related pages - [docs.json reference](https://docs.blode.md/configuration/docs-json) -- configuration file format # Analytics (https://docs.blode.md/features/analytics) Bring your own Google Analytics 4 and PostHog tokens. Blode.md does not ship a proprietary analytics tool. Instead, we inject the analytics you already trust — Google Analytics 4 and PostHog — into every page of your tenant docs. Paste your keys into the dashboard, and the scripts load on the next request. There is nothing to wire up in your content. ## Add a provider 1. Open the dashboard, pick your project, and go to **Settings → Analytics**. 2. Fill in the provider you want: - **Google Analytics 4** — paste your measurement ID, e.g. `G-ABC123DEFG`. Find it in GA4 → Admin → Data streams. - **PostHog** — paste your project API key (starts with `phc_`). Find it in PostHog → Project settings. Personal API keys (`phx_`) are not supported. - **PostHog host** — optional. Defaults to ``us.i.posthog.com`.` Use ``eu.i.posthog.com`` if your project lives in the EU cloud. 3. Save. The next request on your tenant domain loads the scripts. Leave a field empty to disable that provider without touching the other. ## How it works When tenant analytics are configured, every request through the docs proxy carries a compact, tenant-scoped header that the root layout reads on the server. We inject: - `` from `@next/third-parties/google`, which handles App Router SPA pageviews for you. - A small PostHog provider that initializes `posthog-js` with `capture_pageview: false` and emits a `$pageview` event on every client-side navigation. Both providers only load when `VERCEL_ENV === "production"`, so local dev previews and preview deployments never pollute your numbers. > [!INFO] > GA4 and PostHog keys are public client-side tokens — they are designed to be > shipped to the browser. Blode.md treats them as tenant configuration, not > secrets, and surfaces them in the dashboard as-is. ## Consent Mode v2 When GA4 is configured, we ship a default-denied Consent Mode v2 bootstrap: ```js gtag("consent", "default", { ad_storage: "denied", ad_user_data: "denied", ad_personalization: "denied", analytics_storage: "denied", wait_for_update: 500, }); ``` This keeps you compliant with EU traffic until you install a full Consent Management Platform. When you are ready, emit your own `gtag('consent', 'update', …)` calls from your CMP. ## Managing from the CLI The same config is available through `blodemd analytics`: ```bash blodemd analytics get --project my-docs blodemd analytics set ga4 G-ABC123DEFG --project my-docs blodemd analytics set posthog phc_abc... --host `eu.i.posthog.com` --project my-docs blodemd analytics unset posthog --project my-docs ``` See the [CLI reference](https://docs.blode.md/cli/analytics) for all options. # Content types (https://docs.blode.md/features/collections) Use collections to publish blogs, courses, products, and more alongside your docs. Blode.md supports more than just documentation. You can publish blogs, courses, product pages, and other content types by defining collections in your configuration. Each collection has its own content directory, URL prefix, and navigation structure. ## Define a collection Collections use the SiteConfig format with a top-level `collections` array. Each collection is an object with its own `id`, `type`, and content root: ```json title="docs.json" { "collections": [ { "id": "docs", "type": "docs", "root": "content/docs", "slugPrefix": "/docs", "navigation": { "groups": [ { "group": "Getting started", "pages": ["index", "quickstart"] } ] } }, { "id": "blog", "type": "blog", "root": "content/blog", "slugPrefix": "/blog", "sort": "date:desc", "index": true } ] } ``` ## Collection properties - `id` (type: string, required: true): Unique identifier for the collection. - `type` (type: string, required: true): The content type. Determines which frontmatter fields are available and how pages are rendered. - `root` (type: string, required: true): Path to the content directory for this collection, relative to the project root. - `slugPrefix` (type: string): URL prefix for all pages in this collection. - `navigation` (type: object): Navigation structure for this collection. Same format as the top-level navigation. - `sort` (type: string): Sort order for listing pages. Format: "field:direction" (e.g., "date:desc"). - `index` (type: boolean, default: false): Whether to auto-generate an index page listing all pages in the collection. ## Available types | Type | Use case | | ---------- | --------------------------------------- | | `site` | General-purpose website pages | | `docs` | Documentation with sidebar navigation | | `blog` | Blog posts sorted by date | | `courses` | Ordered learning content with progress | | `products` | Product pages with pricing and metadata | | `notes` | Short-form notes and snippets | | `forms` | Form pages with input fields | | `sheets` | Spreadsheet-style data pages | | `slides` | Presentation slides | | `todos` | Task lists and checklists | ## Type-specific frontmatter Each collection type supports additional frontmatter fields beyond the standard `title` and `description`. ```mdx title="Blog post" --- title: Launch week recap description: Everything we shipped this week. date: 2025-01-15 tags: - announcements - releases author: Jane Smith image: /images/launch-week.png --- ``` ```mdx title="Course lesson" --- title: Your first lesson description: Getting started with the basics. order: 1 duration: 5m --- ``` ```mdx title="Product page" --- title: Pro plan description: For growing teams. price: 49 currency: USD sku: PRO-001 --- ``` ## Full example Here is a complete `docs.json` that defines both documentation and a blog: ```json title="docs.json" { "name": "My Project", "slug": "my-project", "collections": [ { "id": "docs", "type": "docs", "root": "content/docs", "slugPrefix": "/docs", "navigation": { "groups": [ { "group": "Getting started", "pages": ["index", "quickstart"] }, { "group": "Guides", "pages": ["guides/setup", "guides/deploy"] } ] } }, { "id": "blog", "type": "blog", "root": "content/blog", "slugPrefix": "/blog", "sort": "date:desc", "index": true } ] } ``` > [!INFO] > When you use the `collections` array, it replaces the top-level `navigation` > field. Each collection manages its own navigation independently. # Custom domains (https://docs.blode.md/features/custom-domains) Use your own domain for your documentation site. Every project deployed with blode.md gets a subdomain at `your-slug.blode.md` automatically. You can also point your own domain to your docs site for a fully branded experience. ## Default subdomain When you run `blodemd push`, your docs are published to `{slug}.blode.md`, where `slug` is the project slug resolved from `--project`, `BLODEMD_PROJECT`, or docs.json `slug`. No per-project DNS setup is required because the platform wildcard handles `*.blode.md`. ## Add a custom domain 1. **Choose your domain** Decide whether to use a subdomain (e.g., `docs.example.com`) or an apex domain (e.g., `example.com`). > [!TIP] > Subdomains are recommended. They are simpler to configure and do not interfere with your root domain's other records. 1. **Configure DNS** Add a CNAME record pointing your domain to `cname.vercel-dns.com`. | Type | Name | Value | | ----- | ------ | ---------------------- | | CNAME | `docs` | `cname.vercel-dns.com` | For apex domains, some DNS providers require an `A` record instead of a CNAME. Check your provider's documentation for CNAME flattening or ALIAS record support. 1. **Verify ownership** If prompted, add the TXT verification record provided in your project dashboard: | Type | Name | Value | | ---- | -------------------------- | ------------------------------ | | TXT | `_vercel.docs.example.com` | `vc-domain-verify=...` | 1. **Add the domain in your project settings** Configure the custom domain through Blode.md's custom-domain workflow after your project has been deployed. That control plane provisions the domain on Vercel and returns any verification records you need. ## Apex vs subdomain ## Path prefix If you want your docs mounted at a subpath rather than the domain root, set the path prefix when configuring the custom domain in the control plane. Your documentation will then be accessible at `docs.example.com/docs` instead of `docs.example.com`. > [!NOTE] > The path prefix is applied to all routes, including search, sitemaps, and API > reference pages. --- Content truncated to keep this response under crawler size limits. Use https://docs.blode.md/llms.txt for the full page index and fetch individual .md pages for uncapped content.