This script publishes your Jekyll blog posts to dev.to automatically.
make devto-install
Or manually:
pip install -r script/devto/requirements.txt
# Copy the config template
cp script/devto/config.json.template script/devto/config.json
# Edit the config file and add your API key
# Edit script/devto/config.json and replace YOUR_DEVTO_API_KEY_HERE with your actual API key
Edit script/devto/config.json:
{
"api_key": "YOUR_DEVTO_API_KEY_HERE", // Required: Your dev.to API key
"base_url": "https://thinhdanggroup.github.io", // Your blog's base URL
"canonical_url_template": "https://thinhdanggroup.github.io/{slug}/", // Template for canonical URLs
"organization_id": null, // Optional: If publishing under an organization
"default_series": null // Optional: Default series name for all posts
}
# Test with dry-run (recommended first time)
make devto-dry-run
# Publish a specific post as draft
make devto-post POST=2023-07-20-prompt-engineering
# Publish 5 most recent posts as drafts
make devto-recent N=5
# Publish all posts as drafts
make devto-all
python script/devto/publish_to_devto.py --post 2023-07-20-prompt-engineering --draft
python script/devto/publish_to_devto.py --post 2023-07-20-prompt-engineering
python script/devto/publish_to_devto.py --recent 5 --draft
python script/devto/publish_to_devto.py --all --draft
python script/devto/publish_to_devto.py --all --dry-run
python script/devto/publish_to_devto.py --post 2023-07-20-prompt-engineering --no-upload-images
_posts directoryYour Jekyll front matter is mapped to dev.to as follows:
| Jekyll | Dev.to | Notes |
|---|---|---|
title |
title |
Required |
tags |
tags |
Limited to 4 tags |
header.overlay_image |
main_image |
Cover image (priority 1) |
header.teaser |
main_image |
Cover image (priority 2) |
header.image |
main_image |
Cover image (priority 3) |
image |
main_image |
Cover image (priority 4) |
excerpt |
description |
Article description |
series |
series |
Series name |
The script converts relative image paths to absolute URLs pointing to your blog:
# Before (in your Jekyll blog)

# After (in dev.to)

Dev.to will automatically fetch and cache these images from your blog when you publish.
⚠️ Images must be optimized before publishing!
Dev.to’s CDN may fail to process large images (>1-2MB). Always optimize your images first:
# Optimize banner image
./script/devto/optimize_image.sh assets/images/your-post/banner.png
# Or using make
make devto-optimize-image IMAGE=assets/images/your-post/banner.png
Recommended: Keep images under 700KB for best results.
The script automatically extracts cover images from your Jekyll front matter. It checks in this priority order:
header.overlay_image - Main overlay bannerheader.teaser - Teaser imageheader.image - Header imageimage - Direct image fieldBanner images are uploaded to dev.to’s CDN, ensuring they display correctly.
All published articles include:
---
*This article was originally published on [ThinhDangGroup Blog](https://thinhdanggroup.github.io/your-post/)*
This protects your SEO and drives traffic back to your main blog.
--dry-run first--draft) to review before publishing./script/devto/optimize_image.sh on banner images before publishingconfig.json/assets/base_url in config is correctIf your banner images are too large, optimize them first:
# Using the provided script
./script/devto/optimize_image.sh assets/images/your-banner/banner.png
# Or using ImageMagick directly
brew install imagemagick # if not installed
convert your-banner.png -quality 85 -resize '1200x630>' optimized-banner.png
# Or using macOS sips
sips -Z 1200 your-banner.png --setProperty formatOptions 85
Recommended banner size: 1200x630px, under 500KB for best performance
Dev.to has rate limits on their API:
If you encounter issues:
--dry-run to see what would be published