Hugo2Nostr – Sync your Hugo post with Nostr network

2 hours ago 2

Test CI

This project allows you to publish your Hugo blog posts to the Nostr network as kind:30023 (Article) events, track already published posts, and manage deletions. It also includes debug tools to inspect events on relays.


  • Publish Hugo posts from content/posts/*.md to Nostr.
  • Support multiple frontmatter formats:
    • YAML (---)
    • TOML (+++)
  • Normalize tags and dates automatically.
  • Dry-run mode to preview events before publishing.
  • Debug script to fetch existing articles from relays.
  • Delete script to send deletion events for all articles.
  • Supports multiple relays and continues if one relay fails.
  • Environment variable configuration for flexibility.
  • Store all published events in markdown files as metadata (nostr_id).
  • Fetch and sync posts from Nostr back to Hugo if not exists in hugo
  • Delete specific articles by adding delete: true in the post frontmatter
  • Update relay list and change nevent id from frontmatter.

Environment Configuration

You can configure your project using environment variables in a .env file or export them before running scripts.

Example .env file:

# Path to Hugo posts POSTS_DIR="FULLPATH_PROJECT_DIR/content/posts" # Comma-separated list of relays RELAY_LIST="wss://relay.emre.xyz" # Dry-run mode (1 = enable, 0 = disable) DRY_RUN=1 # Your Nostr private key (nsec...) NOSTR_PRIVATE_KEY="nsecXXX"

Load these variables automatically using dotenv or export them in your shell:

export POSTS_DIR="/home/delirehberi/www/hugo-emrexyz/content/posts" export RELAY_LIST="wss://relay.emre.xyz" export DRY_RUN=1 export NOSTR_PRIVATE_KEY="nsecXXX"

Copy .env.example to .env and modify as needed.


1. index.js – Publish posts

Publishes your Hugo posts to the Nostr network.

Command:

Features:

  • Reads all Markdown files in POSTS_DIR.
  • Normalizes dates (default time 08:00 if missing).
  • Parses tags (comma or space separated, strips # if present).
  • Supports dry-run mode:

2. debug.js – Fetch existing articles

Fetches all existing kind:30023 articles by your pubkey from configured relays.

Command:

Behavior:

  • Connects to all relays in RELAY_LIST.
  • Continues fetching even if a relay fails.

3. delete.js – Delete articles

Sends a Nostr deletion event (kind:5) for all articles.

Command:

Behavior:

  • Sends a deletion request per event to all configured relays.
  • Continues if a relay fails.
  • Requires your private key to sign the deletion events.

npm run dry-run

npm run publish

npm run debug

npm run delete-all

npm run delete

npm run sync

npm run update


  • Dry-run mode is recommended before publishing to avoid mistakes.
  • Posts with very old dates may be rejected by some relays; the script normalizes to a safe range.
  • Deletion events only work if your pubkey originally published the events.
  • Supports multiple relays and continues publishing even if one relay fails.

  • Node.js (ESM)
  • nostr-tools
  • glob
  • fs (built-in)
  • dotenv (optional, for .env support)

Feel free to open issues or submit pull requests for improvements or bug fixes.

Read Entire Article