Skip to content

Commit a911590

Browse files
committed
docs: no more robotic patterns, inline over admonitions, etc.
1 parent 96050dd commit a911590

32 files changed

Lines changed: 147 additions & 457 deletions

AGENTS.md

Lines changed: 45 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,32 @@
11
# Operational Guidelines for Gotenberg Documentation
22

3-
You are working on **gotenberg.dev**, the official documentation website for [Gotenberg](https://github.com/gotenberg/gotenberg) a Docker-based API for converting documents to PDF. This is a Docusaurus 3.x site serving the public-facing docs at https://gotenberg.dev. Accuracy and clarity are paramount: users rely on this documentation to integrate Gotenberg into production systems.
3+
You are working on **gotenberg.dev**, the official documentation website for [Gotenberg](https://github.com/gotenberg/gotenberg), a Docker-based API for converting documents to PDF. This is a Docusaurus 3.x site serving the public-facing docs at https://gotenberg.dev. Accuracy and clarity are paramount: users rely on this documentation to integrate Gotenberg into production systems.
44

55
## Mandatory Workflow
66

77
Every task follows these five steps **in order**. Do not skip or reorder them.
88

9-
### Step 1 Plan
9+
### Step 1: Plan
1010

1111
Before writing any code or content:
1212

1313
1. State the problem or request.
1414
2. Propose a solution.
1515
3. List alternatives when pertinent.
16-
4. Define scope which files will be created, modified, or deleted.
16+
4. Define scope: which files will be created, modified, or deleted.
1717
5. Describe the verification strategy.
1818

1919
**Wait for user approval before proceeding.**
2020

21-
### Step 2 Implement
21+
### Step 2: Implement
2222

2323
Execute the approved plan. After implementation, verify the site builds cleanly:
2424

2525
```bash
2626
npm run build
2727
```
2828

29-
### Step 3 Test
29+
### Step 3: Test
3030

3131
Verify the changes:
3232

@@ -36,31 +36,36 @@ Verify the changes:
3636
- Components render correctly at desktop (1440px), laptop (1024px), and tablet (768px) widths.
3737
- No console errors or React warnings in the browser.
3838

39-
### Step 4 Review
39+
### Step 4: Review
4040

4141
Self-review against this checklist, then present findings to the user:
4242

4343
- [ ] **Accuracy.** Every endpoint path, form field name, code sample, and configuration flag matches the actual Gotenberg API.
4444
- [ ] **Backward compatibility.** No broken links, no removed content without replacement, no changed URLs.
4545
- [ ] **Consistency.** Follows established page structure, component usage, and terminology.
4646
- [ ] **Code quality.** Formatted with Prettier (`npm run format`), no linting errors, no unused imports.
47-
- [ ] **Documentation.** Shared partials used where appropriate — no duplicated content across pages.
47+
- [ ] **Documentation.** Shared partials used where appropriate. No duplicated content across pages.
4848
- [ ] **Build.** `npm run build` passes without errors or warnings.
4949

50-
### Step 5 Commit
50+
### Step 5: Commit
5151

5252
**Only after explicit user approval.**
5353

5454
- Use [Conventional Commits](https://www.conventionalcommits.org/) (e.g., `docs:`, `feat:`, `fix:`, `style:`).
55-
- Stage specific files only — never `git add -A` or `git add .`.
55+
- Stage specific files only. Never `git add -A` or `git add .`.
5656
- Write a concise commit message that explains _why_, not just _what_.
5757

5858
---
5959

6060
## Core Principles
6161

6262
- **Accuracy is law.** Every code sample, form field name, endpoint path, and configuration flag must match the actual Gotenberg API. When in doubt, cross-reference with the [Gotenberg source](https://github.com/gotenberg/gotenberg).
63-
- **User-first writing.** Write for developers who want to get things done. Lead with the most common use case, then cover edge cases.
63+
- **Direct, confident tone.** Short declarative sentences. No filler words, no hedging ("you might want to", "please feel free to"). Say what something does, not what it is. Lead with the action or outcome.
64+
- **No robotic patterns.** Never start with "This endpoint...", "This route...", or "Use the X form field to...". Describe what it does for the user, not what the object is.
65+
- **Inline over admonitions.** Integrate warnings and notes into prose. Reserve `:::info`, `:::warning`, `:::danger` for genuinely critical information that must stand out. Most pages should have zero or one admonition.
66+
- **No "we" hedging.** Avoid "We do not recommend...", "We offer...", "We have...". Speak directly: "Don't expose...", "There's a dedicated image...".
67+
- **One sentence, not two.** If the second sentence restates the first with more words, delete it.
68+
- **No em dashes.** Never use `` in any markdown file. Use a period, colon, or comma instead.
6469
- **Consistency.** Follow established patterns for page structure, component usage, and terminology. Every API doc page uses the same layout and components.
6570
- **No broken builds.** The site must build cleanly (`npm run build`) before any change is considered complete.
6671

@@ -78,13 +83,13 @@ Self-review against this checklist, then present findings to the user:
7883

7984
All API endpoint documentation uses the `<ApiEndpoint>` React component (`src/components/documentation/ApiEndpoint.js`). It accepts:
8085

81-
- `method` HTTP method (GET, POST, HEAD)
82-
- `path` Endpoint path (e.g., `/forms/chromium/convert/html`)
83-
- `headers` Array of `{ name, type, required, description }` objects
84-
- `formFields` Array of `{ name, type, required, description, defaultValue }` objects
85-
- `formFiles` Array of `{ name, type, required, description }` objects
86-
- `curl` Example cURL command string
87-
- `responses` Array of `{ status, description, body }` objects
86+
- `method`: HTTP method (GET, POST, HEAD)
87+
- `path`: Endpoint path (e.g., `/forms/chromium/convert/html`)
88+
- `headers`: Array of `{ name, type, required, description }` objects
89+
- `formFields`: Array of `{ name, type, required, description, defaultValue }` objects
90+
- `formFiles`: Array of `{ name, type, required, description }` objects
91+
- `curl`: Example cURL command string
92+
- `responses`: Array of `{ status, description, body }` objects
8893

8994
### Shared MDX Partials
9095

@@ -118,24 +123,26 @@ Content for writing or editing documentation pages (new pages, fixing docs, rewo
118123

119124
### Page Structure Convention
120125

121-
Every API endpoint documentation page follows this exact structure:
126+
Every API endpoint documentation page follows this structure:
122127

123-
1. **Frontmatter** `id` and `title` fields
124-
2. **Imports** Shared MDX partials and React components
125-
3. **Intro paragraph** One or two sentences explaining what the endpoint does
126-
4. **`<ConfigurationInfo />`** Links to the configuration page for related flags
127-
5. **`## Basics`** The `<ApiEndpoint>` component with method, path, headers, form fields/files, cURL example, and responses
128-
6. **Feature sections** — Imported shared partials (`<Assets />`, `<RenderingBehaviorPDF />`, `<HeaderFooter />`, etc.)
129-
7. **`<Sponsors />`** Sponsor component at the bottom
128+
1. **Frontmatter:** `id` and `title` fields
129+
2. **Imports:** Shared MDX partials and React components
130+
3. **Intro line:** One direct sentence saying what the endpoint does
131+
4. **Configuration link:** Links to the configuration page for related flags (Chromium/LibreOffice pages)
132+
5. **`## Basics`:** The `<ApiEndpoint>` component with method, path, headers, form fields/files, cURL example, and responses. Only used on pages with multiple sections; single-section pages skip this heading.
133+
6. **Feature sections:** Each sub-section owns its form fields directly (no summary-then-detail duplication). Shared partials with `showFormFields={true}` render their own field definitions.
134+
7. **`<Sponsors />`:** Sponsor component at the bottom
130135

131-
Do not deviate from this structure. New pages must follow existing pages as templates.
136+
New pages must follow existing pages as templates.
132137

133138
### Writing Style
134139

135-
- **Be direct.** Lead with what the endpoint does, not background context.
136-
- **Use second person.** "You can", "your files", not "the user can".
137-
- **Keep paragraphs short.** Two to four sentences maximum.
140+
- **Short, declarative sentences.** Say what it does, then stop. No filler, no hedging.
141+
- **Lead with the action.** "Merges multiple PDF files" not "This endpoint allows you to merge multiple PDF files".
142+
- **Use second person sparingly.** "your files", "your HTML", but don't overuse "you can".
138143
- **Prefer active voice.** "Gotenberg converts the file" not "The file is converted by Gotenberg".
144+
- **Inline over admonitions.** Integrate caveats into prose. Only use `:::info`, `:::warning`, `:::danger` for genuinely critical information.
145+
- **No "Use the X form field to..." pattern.** Describe the outcome directly: "Inject XMP metadata into the PDF" not "Use the `metadata` form field to inject XMP metadata".
139146
- **Use inline code** for all technical terms: form field names (`url`), header names (`Gotenberg-Trace`), endpoint paths (`/forms/chromium/convert/url`), file names (`index.html`), CLI flags (`--api-port`), and environment variables.
140147

141148
### ApiEndpoint Component Usage
@@ -187,10 +194,10 @@ Key rules:
187194

188195
Reusable documentation blocks live in `_shared/` directories:
189196

190-
- `docs/convert-with-chromium/_shared/` Chromium features (assets, console, encryption, header/footer, HTTP networking, rendering behavior, structure metadata, PDF/A, split/page ranges)
191-
- `docs/_shared/` PDF engine features (attachments, encryption, flatten, metadata, PDF/A-UA, syntax validation)
197+
- `docs/convert-with-chromium/_shared/`: Chromium features (assets, console, encryption, header/footer, HTTP networking, rendering behavior, structure metadata, PDF/A, split/page ranges)
198+
- `docs/_shared/`: PDF engine features (attachments, encryption, flatten, metadata, PDF/A-UA, syntax validation)
192199

193-
When a feature applies to multiple endpoints, it MUST be a shared partial. Never duplicate content across pages — import the partial instead.
200+
When a feature applies to multiple endpoints, it MUST be a shared partial. Never duplicate content across pages. Import the partial instead.
194201

195202
### Admonitions
196203

@@ -226,7 +233,7 @@ When adding a new page, update `sidebars.js`:
226233

227234
### Versioning
228235

229-
The site supports versioned documentation (`versioned_docs/`, `versions.json`). Current docs live in `docs/`. Do not modify versioned docs unless explicitly asked — changes to `docs/` apply to the current (next) version only.
236+
The site supports versioned documentation (`versioned_docs/`, `versions.json`). Current docs live in `docs/`. Do not modify versioned docs unless explicitly asked. Changes to `docs/` apply to the current (next) version only.
230237

231238
---
232239

@@ -238,7 +245,7 @@ Content for modifying site design, React components, styles, or layout (CSS, the
238245

239246
- **Framework:** Docusaurus 3.8.1 (React 18)
240247
- **Styling:** CSS Modules (`.module.css`) for components, global CSS (`src/css/custom.css`) for theme overrides
241-
- **Fonts:** Inter (body, headings), JetBrains Mono (code) loaded via Google Fonts
248+
- **Fonts:** Inter (body, headings), JetBrains Mono (code), loaded via Google Fonts
242249
- **Icons:** Inline SVGs in React components (no icon library)
243250
- **Images:** `@docusaurus/plugin-ideal-image` for optimized images
244251

@@ -275,7 +282,7 @@ HTTP method badge colors:
275282
- Max content width: 840px (`.theme-doc-markdown`)
276283
- Container width: 1366px
277284
- Navbar height: 4rem
278-
- Light mode only dark mode switch is disabled
285+
- Light mode only (dark mode switch is disabled)
279286

280287
### Component Architecture
281288

@@ -307,7 +314,7 @@ Renders sponsor logos at the bottom of documentation pages.
307314

308315
### Theme Overrides
309316

310-
- `src/theme/DocSidebar/index.js` Custom sidebar with HTTP method badges via CSS pseudo-elements
317+
- `src/theme/DocSidebar/index.js`: Custom sidebar with HTTP method badges via CSS pseudo-elements
311318
- Sidebar badges are implemented purely in CSS using `::before` pseudo-elements on `.sidebar-method-*` classes
312319

313320
### CSS Conventions
@@ -321,10 +328,10 @@ Renders sponsor logos at the bottom of documentation pages.
321328

322329
### Docusaurus Integration
323330

324-
- Respect Docusaurus's Infima CSS framework — override with specificity, not `!important` (except documented exceptions)
331+
- Respect Docusaurus's Infima CSS framework. Override with specificity, not `!important` (except documented exceptions).
325332
- Use `@docusaurus/Link` for internal navigation, not `<a>` tags
326333
- Use `useBaseUrl` for static asset paths
327-
- Swizzled components live in `src/theme/` — be cautious when upgrading Docusaurus
334+
- Swizzled components live in `src/theme/`. Be cautious when upgrading Docusaurus.
328335

329336
### Responsive Design
330337

docs/_shared/_attachments_pdfengines.mdx

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,6 @@
11
import ApiEndpoint from "@site/src/components/documentation/ApiEndpoint";
22

3-
Use the `embeds` form field to attach external files directly inside the PDF container.
4-
5-
**Common Use Case:**
6-
This is essential for e-invoicing standards like **[ZUGFeRD / Factur-X](https://fnfe-mpe.org/factur-x/)**, which require a human-readable PDF to
7-
carry a machine-readable XML invoice as an attachment.
3+
Attach external files directly inside the PDF container. Commonly used for e-invoicing standards like **[ZUGFeRD / Factur-X](https://fnfe-mpe.org/factur-x/)**, which require a machine-readable XML invoice as an attachment.
84

95
{(props.showFormFields || props.showCurlExample) && (
106

docs/_shared/_encryption_pdfengines.mdx

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,8 @@
11
import ApiEndpoint from "@site/src/components/documentation/ApiEndpoint";
22

3-
Secure your PDF by setting passwords that control access and permissions.
3+
Set passwords to control PDF access. The **user password** is required to open the PDF; the **owner password** controls permissions (printing, copying, editing).
44

5-
- **User Password:** Required to **open** and view the PDF.
6-
- **Owner Password:** Required to **modify** permissions (e.g., printing, copying text, extracting pages).
7-
8-
:::info PDF Engine Dependency
9-
10-
The encryption strength (e.g., AES-256) depends on the configured PDF Engine (QPDF, pdfcpu, or PDFtk).
11-
12-
Check the [PDF Engines Configuration](/docs/configuration#pdf-engines) to see which engine is active.
13-
14-
:::
5+
Encryption strength (e.g., AES-256) depends on the active PDF Engine. See [PDF Engines Configuration](/docs/configuration#pdf-engines).
156

167
{props.showFormFields && props.showCurlExample && (
178

docs/_shared/_flatten_pdfengines.mdx

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
import ApiEndpoint from "@site/src/components/documentation/ApiEndpoint";
22

3-
Use the `flatten` form field to make the PDF non-interactive.
4-
5-
This process merges all interactive form fields (text inputs, checkboxes, etc.) directly into the page content.
6-
The resulting PDF cannot be modified by the end-user.
3+
Merges all interactive form fields (text inputs, checkboxes, etc.) into the page content, making the PDF non-editable.
74

85
{(props.showFormFields || props.showCurlExample) && (
96

docs/_shared/_metadata_pdfengines.mdx

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,8 @@
11
import ApiEndpoint from "@site/src/components/documentation/ApiEndpoint";
22

3-
Use the `metadata` form field to inject XMP metadata into the generated PDF. This allows you to set properties like
4-
**Author**, **Title**, **Copyright**, and **Keywords** by passing a **JSON-formatted object**.
3+
Inject XMP metadata (Author, Title, Copyright, Keywords, etc.) into the PDF as a JSON object.
54

6-
:::info Valid Keys
7-
8-
Not all metadata tags are writable. Gotenberg relies on ExifTool for this operation.
9-
[See the XMP Tag Name documentation](https://exiftool.org/TagNames/XMP.html#pdf) for a list of potential keys.
10-
11-
:::
12-
13-
:::caution Compliance Warning
14-
15-
Writing metadata involves modifying the PDF structure and usually breaks **PDF/A** compliance.
16-
17-
:::
5+
Not all tags are writable. Gotenberg uses ExifTool under the hood. See the [XMP Tag Name documentation](https://exiftool.org/TagNames/XMP.html#pdf) for valid keys. Writing metadata usually breaks **PDF/A** compliance.
186

197
{(props.showFormFields || props.showCurlExample) && (
208

docs/_shared/_pdfa_pdfua_pdfengines.mdx

Lines changed: 3 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,10 @@
11
import ApiEndpoint from "@site/src/components/documentation/ApiEndpoint";
22

3-
Use the `pdfa` and `pdfua` form fields to convert the result into a standardized PDF format during _post-processing_.
3+
Converts to PDF/A (archival) or PDF/UA (accessibility) during post-processing using LibreOffice. Slower than native conversion (requires a second pass).
44

5-
- **Process:** Gotenberg generates the result, then re-processes it using LibreOffice (the only engine supporting these standards).
6-
- **Performance:** Slower (requires a second conversion pass).
7-
- **Result:** A compliant PDF/A (Archival) or PDF/UA (Universal Accessibility) document.
5+
PDF/A and encryption are mutually exclusive: requesting both returns `400 Bad Request`. PDF/A-1b and PDF/A-2b don't support file attachments; use PDF/A-3b if you need both.
86

9-
:::danger
10-
11-
PDF/A and encryption are mutually exclusive — requesting both returns a `400 Bad Request`.
12-
13-
:::
14-
15-
:::warning
16-
17-
PDF/A-1b and PDF/A-2b do not support file attachments. Use PDF/A-3b if you need both archival compliance and embedded files.
18-
19-
:::
20-
21-
:::info Metadata Limitation
22-
23-
When PDF/A conversion runs alongside other post-processing features, LibreOffice overwrites certain XMP metadata fields during the compliance pass. The `CreateDate`, `ModDate`, and `Keywords` fields are not reliably user-controllable in these scenarios. Other metadata fields (`Author`, `Copyright`, `Creator`, `Producer`, `Subject`, `Title`, `Trapped`, `Marked`) are correctly preserved.
24-
25-
:::
7+
When PDF/A runs alongside other post-processing, LibreOffice overwrites `CreateDate`, `ModDate`, and `Keywords`. Other metadata fields are preserved.
268

279
{props.showFormFields && props.showCurlExample && (
2810

docs/_shared/_rotate_pdfengines.mdx

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,6 @@
11
import ApiEndpoint from "@site/src/components/documentation/ApiEndpoint";
22

3-
Rotates pages of the PDF by a given angle during post-processing.
4-
5-
- **Process:** Gotenberg generates the PDF, then rotates the specified pages using a PDF Engine.
6-
- **Performance:** Slower (requires a second pass).
7-
- **Angles:** `90`, `180`, or `270` degrees.
3+
Rotates pages by `90`, `180`, or `270` degrees during post-processing.
84

95
{props.showCurlExample && (
106

docs/_shared/_stamp_pdfengines.mdx

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,7 @@
11
import ApiEndpoint from "@site/src/components/documentation/ApiEndpoint";
22
import SyntaxStampPDFEngines from "./_syntax_stamp_pdfengines.mdx";
33

4-
Adds a stamp _on top of_ the content of each page using a PDF Engine during post-processing.
5-
6-
- **Process:** Gotenberg generates the PDF, then applies the stamp using a PDF Engine.
7-
- **Performance:** Slower (requires a second pass).
8-
- **Sources:** Use `text` for a simple label, `image` to overlay an uploaded image, or `pdf` to stamp a full-page PDF on top.
4+
Adds a stamp _on top of_ the content of each page during post-processing. Sources: `text`, `image`, or `pdf`.
95

106
<SyntaxStampPDFEngines />
117

docs/_shared/_watermark_pdfengines.mdx

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,7 @@
11
import ApiEndpoint from "@site/src/components/documentation/ApiEndpoint";
22
import SyntaxWatermarkPDFEngines from "./_syntax_watermark_pdfengines.mdx";
33

4-
Adds a watermark _behind_ the content of each page using a PDF Engine during post-processing.
5-
6-
- **Process:** Gotenberg generates the PDF, then applies the watermark using a PDF Engine.
7-
- **Performance:** Slower (requires a second pass).
8-
- **Sources:** Use `text` for a simple label, `image` to tile an uploaded image, or `pdf` to stamp a full-page PDF underneath.
4+
Adds a watermark _behind_ the content of each page during post-processing. Sources: `text`, `image`, or `pdf`.
95

106
<SyntaxWatermarkPDFEngines />
117

0 commit comments

Comments
 (0)