@onozaty/growi-uploader
v1.7.1
Published
A content uploader for GROWI
Readme
growi-uploader
English | 日本語
A CLI tool to batch upload local Markdown files and attachments to GROWI Wiki.
Features
- 📁 Preserves directory structure - Local folder hierarchy becomes GROWI page hierarchy
- 📝 Markdown file upload - Creates or updates GROWI pages from
.mdfiles - 📎 Automatic attachment detection - Files matching
<page>_attachment_<file>pattern are uploaded as attachments - 🔗 Link replacement - Automatically converts local attachment links to GROWI format (
/attachment/{id}) - 🖼️ Image embedding - Supports image links (
) with automatic conversion - ⚙️ Flexible configuration - Control base path, update behavior, and more
Quick Start
- Create a configuration file
growi-uploader.json:
{
"url": "https://your-growi-instance.com",
"token": "your-api-token",
"basePath": "/",
"update": false
}- Run with npx (no installation required):
npx @onozaty/growi-uploader ./docsThat's it! Your local ./docs directory will be uploaded to GROWI.
Installation
Using npx (Recommended)
No installation required. Just run:
npx @onozaty/growi-uploader <source-dir>Global Installation
For frequent use, you can install globally:
npm install -g @onozaty/growi-uploader
growi-uploader <source-dir>Usage
Basic Command
growi-uploader <source-dir> [options]Arguments:
<source-dir>: Path to the directory containing Markdown files
Options:
-c, --config <path>: Path to config file (default:growi-uploader.json)-v, --verbose: Enable verbose error output with detailed information-V, --version: Output the version number-h, --help: Display help information
Examples
# Upload with default config file
npx @onozaty/growi-uploader ./docs
# Upload with custom config file
npx @onozaty/growi-uploader ./docs -c my-config.json
# Upload with verbose error output
npx @onozaty/growi-uploader ./docs --verboseDirectory Structure Example
Local Directory
docs/
guide.md
guide_attachment_diagram.svg
guide_attachment_sample.txt
api/
overview.md
overview_attachment_example.json
authentication.mdResulting GROWI Pages
/docs/guide (from guide.md)
└─ diagram.svg (attachment)
└─ sample.txt (attachment)
/docs/api/overview (from api/overview.md)
└─ example.json (attachment)
/docs/api/authentication (from api/authentication.md)Page Name Normalization
To prevent API errors, page names are automatically normalized using the following rules:
Normalization Rules
Spaces around slashes → Replaced with underscores
a / b.md→/a_/_b
Special characters → Replaced with safe alternatives:
+→-plus-?→-question-*→-asterisk-$→-dollar-^→-caret-%→-percent-
Reserved page names → Suffixed with underscore:
edit→edit_(only when it's the last path segment)
Examples
Local file GROWI page path
──────────────────────────────────────────────────
C++.md → /C-plus--plus-
What?.md → /What-question-
C++ / Python?.md → /C-plus--plus-_/_Python-question-
edit.md → /edit_
docs/edit.md → /docs/edit_
docs/normal-page.md → /docs/normal-page (no change)This normalization ensures compatibility with GROWI's page naming requirements while preserving the readability of your file names.
Configuration File
Create a growi-uploader.json file in your project root:
{
"url": "https://your-growi-instance.com",
"token": "your-api-token",
"basePath": "/imported",
"update": true,
"verbose": false
}Configuration Options
| Option | Type | Required | Default | Description |
|--------|------|----------|---------|-------------|
| url | string | ✅ | - | GROWI instance URL |
| token | string | ✅ | - | GROWI API access token |
| basePath | string | ❌ | / | Base path for imported pages |
| update | boolean | ❌ | false | Update existing pages if true, skip if false |
| verbose | boolean | ❌ | false | Enable verbose error output with detailed information |
Getting an API Token
- Log in to your GROWI instance
- Go to User Settings → API Settings
- Click Issue new token
- Copy the generated token to your config file
Attachment Files
Attachments are automatically detected using two methods:
Method 1: Naming Convention
Files following this naming pattern are detected as attachments:
<page-name>_attachment_<filename>Example:
guide.md → GROWI page: /guide
guide_attachment_image.png → Attached to /guide
guide_attachment_document.pdf → Attached to /guideMethod 2: Link-Based Detection
Files referenced in markdown links are automatically detected as attachments:
Local Directory:
guide.md
assets/
banner.png
images/
logo.png
screenshot.pngguide.md Content:


All referenced files (logo.png, screenshot.png, and banner.png) will be uploaded as attachments to the /guide page, even though they don't follow the _attachment_ naming convention.
Path resolution:
- Markdown escape sequences are unescaped (
\(→() - URL encoding (percent-encoding) is decoded (
%20→ space,%E7%94%BB%E5%83%8F→画像) - Relative paths (
./,../, or no prefix): Resolved from the Markdown file's directory - Absolute paths (starting with
/): Resolved from the source directory root- Example:
/assets/banner.png→<source-dir>/assets/banner.png
- Example:
Supported link formats:
 # Standard relative path
 # Relative path without ./
 # URL-encoded Japanese filename
[File](./docs/my%20file.pdf) # URL-encoded space
[File](<./path/file (1).png>) # Special chars with angle brackets
.png) # Special chars with escaping
<img src="./images/logo.png" alt="Logo"> # HTML img tag (double quotes)
<img src='./images/logo.png' alt='Logo'> # HTML img tag (single quotes)Excluded from detection:
.mdfiles (treated as page links)- External URLs (
http://,https://) - Non-existent files
Automatic Link Replacement
Markdown links to attachments are automatically converted to GROWI format (/attachment/{id}).
Example (Naming Convention):
# Before upload

Download the [documentation](guide_attachment_document.pdf).
# After upload (on GROWI)

Download the [documentation](/attachment/68f3a3fa794f665ad2c0d2b3).Example (Link-Based):
# Before upload

# After upload (on GROWI)
Both detection methods support multiple link formats (with or without ./).
Cross-Page References
When a file following the naming convention (BBB_attachment_*) is referenced from a different page (AAA.md):
- The attachment is uploaded only to its owner page (
/BBB) - Links in the referencing page (
AAA.md) are replaced with the attachment URL (/attachment/{id})
Example:
File structure:
AAA.md (contains: )
BBB.md
BBB_attachment_image.png
Result:
- BBB_attachment_image.png is uploaded to /BBB page only
- The link in AAA.md is replaced with /attachment/{id}Page Link Conversion
Links to other Markdown files (.md extension) are automatically converted to GROWI format.
Supported Patterns
# Before upload (local)
[User Guide](./guide.md)
[API Overview](../api/overview.md)
[Auth Section](./api/auth.md#setup)
# After upload (on GROWI)
[User Guide](./guide)
[API Overview](../api/overview)
[Auth Section](./api/auth#setup)- The
.mdextension is removed - Relative path prefixes (
./,../) are preserved (GROWI supports relative links) - Anchor links (
#section) are preserved - External URLs (
http://,https://) are not modified
Advanced Usage
Update Existing Pages
Set update: true in your config file to update existing pages:
{
"url": "https://your-growi-instance.com",
"token": "your-api-token",
"update": true
}Import to Specific Path
Use basePath to import all pages under a specific path:
{
"url": "https://your-growi-instance.com",
"token": "your-api-token",
"basePath": "/imported"
}Result:
docs/guide.md → /imported/docs/guideOutput Example
Found 5 Markdown file(s) and 3 attachment(s)
[SUCCESS] docs/guide.md → /docs/guide (created)
[SUCCESS] docs/guide_attachment_diagram.svg → /docs/guide (attachment)
[SUCCESS] docs/guide.md → /docs/guide (attachment links replaced)
[SUCCESS] docs/api/overview.md → /docs/api/overview (created)
[SKIP] docs/api/auth.md → /docs/api/auth (page already exists)
Completed:
- Pages created: 2
- Pages updated: 0
- Pages skipped: 1
- Page errors: 0
- Attachments uploaded: 2
- Attachments skipped: 0
- Attachment errors: 0
- Link replacement errors: 0Requirements
- Node.js 18 or later
- GROWI instance with REST API v3 support
License
MIT
