GitHub - SemanticSearch-ai/hexo-plugin: Hexo plugin for AI-powered semantic search and related posts. Build a free vector search engine for your blog with Cloudflare Workers.

3 min read Original article ↗

A Hexo plugin that integrates SemanticSearch for AI-powered semantic search and related posts.

Demos

Features

  • Automatic Indexing: Syncs posts to SemanticSearch after hexo generate
  • Incremental Sync: Only syncs changed posts (tracks content hash)
  • Related Posts: Generates related posts at build time using semantic similarity
  • Search Component: Provides helpers for frontend search UI
  • Customizable: Full control over styling and rendering

Installation

npm install hexo-semantic-search-ai --save

Prerequisites

You need a SemanticSearch instance. Deploy one for free on Cloudflare Workers:

  1. Go to SemanticSearch
  2. Click "Deploy to Cloudflare"
  3. Get your API endpoint and keys

Configuration

Add to your Hexo _config.yml:

semantic_search:
  enable: true
  endpoint: https://your-search.your-subdomain.workers.dev
  writer_key: ${SEMANTIC_SEARCH_WRITER_KEY}  # Use env var for security
  reader_key: your-reader-key                 # Public, safe to expose

  # Sync settings
  sync:
    auto: true                    # Auto-sync after hexo generate
    fields:                       # Fields to index
      - title
      - content
      - excerpt
      - tags
      - categories

  # Related posts settings
  related_posts:
    enable: true
    limit: 5                      # Max related posts per article
    min_score: 0.3                # Minimum similarity score (0-1)
    query_fields:                 # Fields used to find related posts
      - title
      - excerpt

  # Search UI settings
  search:
    placeholder: "Search..."

Environment Variables

For security, use environment variables for your writer key:

export SEMANTIC_SEARCH_WRITER_KEY=your-writer-key

Usage

Search Box

Add a search box to your theme:

<%- semantic_search_box() %>

With options:

<%- semantic_search_box({
  placeholder: 'Search articles...',
  class: 'my-search-box',
  id: 'custom-search'
}) %>

Don't forget to include the JS file:

<script src="<%- url_for('/js/semantic-search.js') %>"></script>

Related Posts

Display related posts in your post template:

<%- semantic_related_posts() %>

With options:

<%- semantic_related_posts({
  limit: 3,
  title: 'You might also like',
  class: 'related-articles',
  excerpt: false
}) %>

Custom Rendering

For full control, access the raw data:

<% if (has_semantic_related()) { %>
  <div class="my-related-posts">
    <h3>Related</h3>
    <% get_semantic_related().forEach(function(post) { %>
      <article>
        <a href="<%= post.url %>"><%= post.title %></a>
        <p><%= post.excerpt %></p>
      </article>
    <% }); %>
  </div>
<% } %>

Frontend JavaScript API

For advanced use cases, use the JavaScript API directly:

<script src="/js/semantic-search.js"></script>
<script>
  // Configure (if not using helper)
  SemanticSearch.configure({
    endpoint: 'https://your-search.workers.dev',
    readerKey: 'your-reader-key'
  });

  // Search
  SemanticSearch.search('how to deploy').then(results => {
    console.log(results);
  });

  // Or bind to an input
  SemanticSearch.bindSearchBox('#search-input', '#search-results', {
    limit: 10,
    debounce: 300,
    minLength: 2
  });
</script>

Commands

Sync manually

# Incremental sync (only changed posts)
hexo semantic-search sync

# Force full sync
hexo semantic-search sync --force
# or
hexo semantic-search full-sync

# Check sync status
hexo semantic-search status

State File

The plugin creates .semantic-search-state.json in your Hexo root to track synced posts. Add it to .gitignore if you don't want to commit it:

.semantic-search-state.json

Helpers Reference

Helper Description
semantic_search_box(options) Render search input with results container
semantic_search_config() Output config JSON for custom frontend
semantic_related_posts(options) Render related posts list
has_semantic_related() Check if current post has related posts
get_semantic_related() Get raw related posts array

License

MIT

Friendly Request

Friendly request (not required): If you use this plugin, please consider adding a link to https://semanticsearch.ai/ on your website.