|
| 1 | +# Smartbox Documentation |
| 2 | + |
| 3 | +This is a documentation repository for Smartbox. It uses Health Samurai's `docs-tools` for linting, image optimization, and OG image generation. |
| 4 | + |
| 5 | +All documentation is written in **English**. |
| 6 | + |
| 7 | +## Structure |
| 8 | + |
| 9 | +``` |
| 10 | +docs/ — markdown files (documentation pages) |
| 11 | +assets/ — images and downloadable files |
| 12 | +assets/og/ — auto-generated Open Graph images (do not edit) |
| 13 | +SUMMARY.md — table of contents and navigation |
| 14 | +docs-lint.yaml — linter configuration |
| 15 | +redirects.yaml — URL redirects |
| 16 | +``` |
| 17 | + |
| 18 | +## Writing Documentation |
| 19 | + |
| 20 | +### Setup |
| 21 | + |
| 22 | +Run `bun install` once after cloning — this installs docs-tools and sets up git hooks. |
| 23 | + |
| 24 | +`docs-tools` is intentionally unpinned (`github:HealthSamurai/docs-tools`). `bun install` installs the version locked in `bun.lock` without modifying it. CI runs `bun update docs-tools` to pull the latest version and commits the updated `bun.lock` back to the repo. |
| 25 | + |
| 26 | +### Creating a New Page |
| 27 | + |
| 28 | +1. Create a `.md` file in `docs/` (or a subdirectory) |
| 29 | +2. Start the file with a single `# Title` heading |
| 30 | +3. Add the page to `SUMMARY.md` in the correct section |
| 31 | +4. Run `bun lint` to verify everything is correct |
| 32 | + |
| 33 | +### Frontmatter (optional) |
| 34 | + |
| 35 | +Pages can have YAML frontmatter: |
| 36 | + |
| 37 | +```markdown |
| 38 | +--- |
| 39 | +hidden: true |
| 40 | +description: Page description for SEO |
| 41 | +--- |
| 42 | +# Page Title |
| 43 | +``` |
| 44 | + |
| 45 | +- `hidden: true` — page is excluded from orphan-pages lint check |
| 46 | + |
| 47 | +### SUMMARY.md Format |
| 48 | + |
| 49 | +```markdown |
| 50 | +# Table of contents |
| 51 | + |
| 52 | +## Section Name |
| 53 | + |
| 54 | +* [Page Title](page-file.md) |
| 55 | +* [Another Page](subdir/page.md) |
| 56 | +``` |
| 57 | + |
| 58 | +Rules: |
| 59 | +- Page title in SUMMARY.md must match the `# H1` heading in the file |
| 60 | +- Use "and" instead of "&" in titles |
| 61 | +- Every `.md` file in `docs/` must be listed in SUMMARY.md |
| 62 | + |
| 63 | +### Images |
| 64 | + |
| 65 | +Place images in `assets/` directory (use subdirectories to organize, e.g. `assets/getting-started/`). |
| 66 | + |
| 67 | +```markdown |
| 68 | + |
| 69 | +``` |
| 70 | + |
| 71 | +- Always provide meaningful alt text — linter warns on empty `` |
| 72 | +- Supported formats: PNG, JPG, JPEG, GIF, SVG, WebP, AVIF |
| 73 | +- CI automatically converts images to AVIF and updates references — commit as PNG/JPG, optimization happens on push |
| 74 | +- To optimize locally before pushing: `bun images:optimize` |
| 75 | +- Do not edit files in `assets/og/` — these are auto-generated Open Graph images |
| 76 | + |
| 77 | +### Mermaid Diagrams |
| 78 | + |
| 79 | +Mermaid diagrams are supported via ` ```mermaid ` code blocks. They are rendered server-side to SVG (light + dark themes). Use round rectangles `(Node Name)` instead of `[Node Name]` for nodes. No custom CSS classes or inline styles — only the built-in color classes below. |
| 80 | + |
| 81 | +#### Color Classes |
| 82 | + |
| 83 | +Apply colors to nodes using `class NodeName color` or inline `:::color` syntax. The class name is `{color}{width}` where width is the border thickness in pixels (1, 2, or 3). |
| 84 | + |
| 85 | +Available colors: `red`, `blue`, `violet`, `green`, `yellow`, `neutral` |
| 86 | + |
| 87 | +Examples: `red1`, `blue2`, `green3`, `neutral1` |
| 88 | + |
| 89 | +```mermaid |
| 90 | +graph LR |
| 91 | + A(Source):::blue2 --> B(Process):::green2 --> C(Result):::violet2 |
| 92 | + class A blue2 |
| 93 | +``` |
| 94 | + |
| 95 | +Class definitions are auto-injected — do not write `classDef` lines manually. |
| 96 | + |
| 97 | +### Markdown Rules |
| 98 | + |
| 99 | +- Exactly one `# H1` per file (the page title) |
| 100 | +- Do not skip heading levels (H1 → H3 is wrong, use H1 → H2 → H3) |
| 101 | +- No empty headings |
| 102 | +- All internal links must point to existing files |
| 103 | +- All referenced images must exist in `assets/` |
| 104 | +- Images should have meaningful alt text |
| 105 | + |
| 106 | +### Redirects |
| 107 | + |
| 108 | +When renaming or moving a page, add a redirect in `redirects.yaml` so old URLs keep working: |
| 109 | + |
| 110 | +```yaml |
| 111 | +redirects: |
| 112 | + old/path/slug: new/path/to/page.md |
| 113 | + another/old/slug: some/page.md#section-anchor |
| 114 | +``` |
| 115 | +
|
| 116 | +- **Keys** — old URL slugs (no leading `/`, no `.md` extension) |
| 117 | +- **Values** — relative paths to `.md` files in `docs/` directory |
| 118 | +- Section anchors are supported: `page.md#section` redirects to a specific section |
| 119 | +- The linter checks that target `.md` files exist — missing targets cause an error |
| 120 | + |
| 121 | +## Supported Widgets |
| 122 | + |
| 123 | +Widgets can be nested inside each other (e.g. hints inside tabs, code blocks inside steps). |
| 124 | + |
| 125 | +### Hint (callout box) |
| 126 | + |
| 127 | +```markdown |
| 128 | +{% hint style="info" %} |
| 129 | +Informational message. |
| 130 | +{% endhint %} |
| 131 | +``` |
| 132 | + |
| 133 | +Styles: `info`, `success`, `warning`, `danger` |
| 134 | + |
| 135 | +### Tabs |
| 136 | + |
| 137 | +`{% tab %}` must be inside `{% tabs %}`. |
| 138 | + |
| 139 | +```markdown |
| 140 | +{% tabs %} |
| 141 | +{% tab title="First Tab" %} |
| 142 | +Content for tab 1. |
| 143 | +{% endtab %} |
| 144 | +{% tab title="Second Tab" %} |
| 145 | +Content for tab 2. |
| 146 | +{% endtab %} |
| 147 | +{% endtabs %} |
| 148 | +``` |
| 149 | + |
| 150 | +### Stepper (numbered steps) |
| 151 | + |
| 152 | +`{% step %}` must be inside `{% stepper %}`. |
| 153 | + |
| 154 | +```markdown |
| 155 | +{% stepper %} |
| 156 | +{% step %} |
| 157 | +First step content. |
| 158 | +{% endstep %} |
| 159 | +{% step %} |
| 160 | +Second step content. |
| 161 | +{% endstep %} |
| 162 | +{% endstepper %} |
| 163 | +``` |
| 164 | + |
| 165 | +### Code Block with Title |
| 166 | + |
| 167 | +```markdown |
| 168 | +{% code title="config.yaml" %} |
| 169 | +```yaml |
| 170 | +key: value |
| 171 | +``` |
| 172 | +{% endcode %} |
| 173 | +``` |
| 174 | + |
| 175 | +### Embed (YouTube or link card) |
| 176 | + |
| 177 | +```markdown |
| 178 | +{% embed url="https://www.youtube.com/watch?v=VIDEO_ID" / %} |
| 179 | +
|
| 180 | +{% embed url="https://example.com" / %} |
| 181 | +``` |
| 182 | + |
| 183 | +### Content Reference (link card to another page) |
| 184 | + |
| 185 | +```markdown |
| 186 | +{% content-ref %} |
| 187 | +[Page Title](path/to/page.md) |
| 188 | +{% endcontent-ref %} |
| 189 | +``` |
| 190 | + |
| 191 | +### File Download |
| 192 | + |
| 193 | +```markdown |
| 194 | +{% file src="/assets/document.pdf" / %} |
| 195 | +
|
| 196 | +{% file src="/assets/archive.zip" %} |
| 197 | +Download Archive |
| 198 | +{% endfile %} |
| 199 | +``` |
| 200 | + |
| 201 | +### Carousel (image slideshow) |
| 202 | + |
| 203 | +```markdown |
| 204 | +{% carousel %} |
| 205 | + |
| 206 | + |
| 207 | +{% endcarousel %} |
| 208 | +``` |
| 209 | + |
| 210 | +### Quote (testimonial) |
| 211 | + |
| 212 | +```markdown |
| 213 | +{% quote author="Name" title="Position" %} |
| 214 | +Quote text here. |
| 215 | +{% endquote %} |
| 216 | +``` |
| 217 | + |
| 218 | +## Available Commands |
| 219 | + |
| 220 | +``` |
| 221 | +bun lint — fix lint issues automatically |
| 222 | +bun lint:check — check for issues without fixing |
| 223 | +bun images:check — find unoptimized images |
| 224 | +bun images:optimize — convert images to AVIF format |
| 225 | +``` |
| 226 | +
|
| 227 | +## Git Workflow |
| 228 | +
|
| 229 | +- Commit directly to `main` branch |
| 230 | +- After committing, ask the user before pushing |
| 231 | +- Before starting work and before pushing, always pull with rebase: `git pull --rebase` |
| 232 | +
|
| 233 | +### Pre-push Checks |
| 234 | +
|
| 235 | +A pre-push git hook runs `bun lint` automatically before every push. If lint fails, the push is blocked. |
| 236 | +
|
| 237 | +**Before pushing, always run `bun lint` yourself first.** If there are errors: |
| 238 | +1. Show the user what failed |
| 239 | +2. Fix the issues (most are auto-fixable by `bun lint` without `--check`) |
| 240 | +3. Commit the fixes |
| 241 | +4. Only then push |
| 242 | +
|
| 243 | +Common lint errors and how to fix them: |
| 244 | +- **summary-sync** — file exists but not in SUMMARY.md (or vice versa). Add/remove the entry. |
| 245 | +- **title-mismatch** — H1 in file differs from title in SUMMARY.md. Make them match. |
| 246 | +- **broken-links** — internal link points to non-existent file. Fix the path. |
| 247 | +- **missing-images** — referenced image not found in `assets/`. Add the image or fix the path. |
| 248 | +- **h1-headers** — more than one `# H1` in a file. Keep only one. |
| 249 | +- **empty-headers** — heading with no text (`## `). Add text or remove. |
| 250 | +- **heading-order** — skipped heading level (e.g. H1 → H3). Add the missing level. |
| 251 | +- **unparsed-widgets** — unclosed or mismatched widget tags. Close `{% hint %}` with `{% endhint %}`, etc. |
| 252 | +- **broken-references** — leftover GitBook `broken-reference` placeholder. Replace with real link. |
| 253 | +- **image-alt** (warning) — image without alt text. Add ``. |
| 254 | +- **deprecated-links** — link points to a page in a deprecated directory. Update to current page. |
| 255 | +- **absolute-links** — hardcoded absolute URL to own docs domain. Use relative markdown links instead. |
| 256 | +
|
| 257 | +CI automatically optimizes images and generates OG images on push. |
0 commit comments