hugo-syndicate
Version:
Multi-provider content syndication tool for Hugo static sites. Currently supports dev.to and Qiita with extensible architecture for more providers. Works with Hugo source files, not published sites.
390 lines (270 loc) • 8.75 kB
Markdown
<div align="center">
<img src="logo.svg" alt="Hugo Syndicate Logo" width="120" height="120">
# Hugo Syndicate
**Multi-provider content syndication for Hugo static sites**
_Sync your hugo blog posts to dev.to, Qiita and more (coming soon)_
[](https://opensource.org/licenses/Apache-2.0)
[](https://nodejs.org/)
[](https://gohugo.io/)
</div>
---
Hugo Syndicate automatically distributes your Hugo blog posts across multiple platforms.
> **⚠️ This is Alpha Software**: While functional, it may contain bugs and the API may change in future versions. Currently supports dev.to and Qiita. Use in production at your own risk.
## Table of Contents
- [Quick Start](#quick-start)
- [Features](#features)
- [Requirements](#requirements)
- [Installation](#installation)
- [Configuration](#configuration)
- [Usage](#usage)
- [Hugo Front Matter](#hugo-front-matter)
- [GitHub Actions](#github-actions)
- [Provider Details](#provider-details)
- [Troubleshooting](#troubleshooting)
- [Contributing](#contributing)
- [Support](#support)
## Quick Start
1. Install globally:
```bash
npm install -g hugo-syndicate
```
2. Set environment variables:
```bash
export DEVTO_API_KEY=your_devto_key
export QIITA_ACCESS_TOKEN=your_qiita_token
```
3. Mark posts for syndication:
```yaml
---
title: "My Blog Post"
devto: true
qiita: true
---
```
4. Run from your Hugo project root:
```bash
hugo-syndicate
```
## Features
### Current
- **Multi-Provider Architecture**: Extensible provider system supporting multiple platforms
- **Smart Sync Control**: Only syncs posts explicitly marked with provider flags
- **Hugo Shortcode Transformation**: Converts Hugo shortcodes to provider-compatible formats
- **Canonical URL Support**: Generates canonical URLs based on Hugo site structure
- **Git Integration**: Detects changed files to sync only updates
- **Orphaned Article Detection**: Finds and manages articles deleted from Hugo
- **Flexible Configuration**: Environment variables and CLI options
- **Debug Logging**: Multiple levels for detailed operation tracking
### Planned
- Medium, Hashnode, Ghost, WordPress integration
- Official GitHub Action
- Bi-directional sync (import comments/metrics)
- Content scheduling
## Requirements
- **Node.js**: Version 16.0.0 or higher
- **Git**: Required for change detection
- **Hugo Source Files**: Works with markdown + front matter (not published HTML)
- **API Keys**: For the providers you want to use
### Platform Compatibility
- **macOS/Linux**: Full support out of the box
- **Windows**: Requires Git for Windows (Git Bash) or WSL
- **CI/CD**: Compatible with GitHub Actions, GitLab CI, etc.
## Installation
### Global Installation (Recommended)
```bash
npm install -g hugo-syndicate
```
### Local Installation
```bash
npm install hugo-syndicate
```
### Quick Setup Script
```bash
curl -sSL https://raw.githubusercontent.com/px4n/hugo-syndicate/develop/scripts/install.sh | bash
```
## Configuration
### Environment Variables
Create a `.env` file in your Hugo project root:
```bash
# Required: Provider API Keys
DEVTO_API_KEY=your_dev_to_api_key
QIITA_ACCESS_TOKEN=your_qiita_token
# Optional: Configuration
HUGO_BASE_URL=https://yoursite.com
CONTENT_DIR=content/
DEBUG_LEVEL=2
PROVIDERS=devto,qiita
AUTO_DELETE=false
```
### Getting API Keys
- **dev.to**: Settings → Account → [API Keys](https://dev.to/settings/account)
- **Qiita**: Settings → [Applications](https://qiita.com/settings/applications)
## Usage
Run from your Hugo project root directory where your content folder is located.
### Basic Commands
```bash
# Sync changed posts to all configured providers
hugo-syndicate
# Sync to specific provider
hugo-syndicate --provider qiita
# Force sync all posts
hugo-syndicate --force-all
# Auto-delete orphaned articles
hugo-syndicate --auto-delete
# Show help
hugo-syndicate --help
```
### Debug Modes
```bash
# Basic info (default)
DEBUG_LEVEL=2 hugo-syndicate
# Detailed debugging
DEBUG_LEVEL=3 hugo-syndicate
# Verbose (includes API payloads)
DEBUG_LEVEL=4 hugo-syndicate
```
## Hugo Front Matter
Mark posts for syndication in your markdown front matter:
### YAML Format
```yaml
---
title: "My Blog Post"
date: 2025-01-15
tags: ["javascript", "webdev"]
devto: true # Sync to dev.to
qiita: true # Sync to Qiita
syndicate: true # Sync to all providers
draft: false # Must not be draft
---
```
### TOML Format
```toml
+++
title = "My Blog Post"
date = 2025-01-15
tags = ["javascript", "webdev"]
devto = true
qiita = true
draft = false
+++
```
### Sync Rules
Posts are synced when they meet ALL criteria:
1. **Provider flag**: `devto = true`, `qiita = true`, or `syndicate = true`
2. **Not a draft**: `draft = false` (or not set)
3. **Not private**: `visibility != "private"`
4. **Allowed directory**: In blog/, articles/, posts/, tech/, or tutorials/
5. **Post type**: Has type "post" (default)
## GitHub Actions
Example workflow for automatic syncing:
```yaml
name: Sync to Providers
on:
push:
branches: [main]
paths: ["content/**/*.md"]
jobs:
sync:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 2
- uses: actions/setup-node@v4
with:
node-version: "20"
- run: npm install -g hugo-syndicate
- name: Sync to providers
env:
DEVTO_API_KEY: ${{ secrets.DEVTO_API_KEY }}
QIITA_ACCESS_TOKEN: ${{ secrets.QIITA_ACCESS_TOKEN }}
HUGO_BASE_URL: ${{ vars.HUGO_BASE_URL }}
run: hugo-syndicate
```
See `examples/github-workflows/` for more workflow templates.
## Provider Details
### dev.to
**Limitations:**
- Maximum 4 tags per post
- Only alphanumeric tags (a-z, 0-9)
- 150,000 character limit
- Rate limit: 30 requests per 30 seconds
**Tag Examples:**
- ✅ `javascript`, `react`, `webdev`
- ❌ `日本語`, `c++`, `node.js`
### Qiita
**Limitations:**
- Maximum 5 tags per article
- Alphanumeric + hyphens (a-z, 0-9, -)
- Tags converted to lowercase
- 40 character tag limit
**Tag Examples:**
- ✅ `javascript`, `react-hooks`, `web-dev`
- ❌ `日本語`, `c++`, `node.js`
### Internationalization
Hugo Syndicate fully supports international content:
- **Content**: Any language (Japanese, Chinese, Korean, etc.)
- **Titles**: Full Unicode support
- **URLs**: Handles language prefixes (`/ja/blog/...`)
- **Tags**: Limited to ASCII due to API restrictions
## Supported Hugo Shortcodes
Hugo shortcodes are automatically transformed:
```hugo
{{< image src="/images/pic.jpg" alt="Picture" >}}
→ 
{{< youtube dQw4w9WgXcQ >}}
→ {% youtube dQw4w9WgXcQ %}
{{< twitter 1234567890 >}}
→ {% twitter 1234567890 %}
{{< gist username abc123 >}}
→ {% gist abc123 %}
```
## Troubleshooting
### Common Issues
**"Failed to parse front matter"**
- Check YAML syntax (needs `---` delimiters)
- Verify proper indentation
- For TOML use `+++` delimiters
**"No markdown files to process"**
- Ensure posts have provider flags
- Posts must not be drafts
- Use `--force-all` to process all
**"Warning: Tags were removed"**
- dev.to: Only alphanumeric allowed
- Qiita: Alphanumeric + hyphens
- Add ASCII alternatives
**API Authentication Failed**
- Verify API keys are set correctly
- Check token permissions/scopes
- Regenerate if expired
### Recovery from Failed Syncs
```bash
# Re-sync all posts
hugo-syndicate --force-all
# Debug the issue
DEBUG_LEVEL=3 hugo-syndicate
# Check provider dashboards for orphaned drafts
```
## Contributing
Contributions are welcome! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for details.
For provider development, see [Provider Development Guide](docs/PROVIDERS.md).
### Commit Convention
We use [Conventional Commits](https://www.conventionalcommits.org/):
```bash
feat: add Medium provider # Minor version
fix: handle empty responses # Patch version
feat!: change config format # Major version
docs: update installation # No version bump
```
## Release Process
Releases are automated via semantic-release:
1. Commit with conventional format
2. Push to `develop` branch
3. Automatic version bump, changelog, and NPM publish
## License
Apache License 2.0 - see [LICENSE](LICENSE) file
## Support
For issues and questions:
- Check [Troubleshooting](#troubleshooting) section
- Run with `DEBUG_LEVEL=3` for detailed logs
- [Open an issue](https://github.com/px4n/hugo-syndicate/issues) with details