RaisFastRaisFast
SSG Integration

Hexo + RaisFast

Add comments, search, auth, and ecommerce to your Hexo blog with RaisFast as the backend.

Overview

Hexo is the most popular static blog framework for Chinese developers. RaisFast adds the backend capabilities that Hexo lacks — comments, search, user authentication, and even ecommerce and payment.

Hexo    → generates static blog pages
RaisFast → comments, search, auth, ecommerce, payment

Prerequisites

Step 1: Start RaisFast

raisfast

Step 2: Configure Hexo to Connect to RaisFast

Add RaisFast configuration to your _config.yml:

# _config.yml
raisfast:
  apiBase: http://localhost:9898/api/v1
  enableComments: true
  enableSearch: true

Step 3: Add Comments

Create a Hexo comment partial at layout/_partial/raisfast-comments.ejs:

<!-- layout/_partial/raisfast-comments.ejs -->
<% if (config.raisfast && config.raisfast.enableComments) { %>
<div id="raisfast-comments" data-post-id="<%= page.path %>"></div>
<script>
  (function() {
    var apiBase = '<%= config.raisfast.apiBase %>';
    var postId = document.getElementById('raisfast-comments').dataset.postId;

    fetch(apiBase + '/comments?post_id=' + encodeURIComponent(postId))
      .then(function(r) { return r.json(); })
      .then(function(data) {
        var html = '';
        data.data.items.forEach(function(c) {
          html += '<div class="comment"><strong>' + c.author_name + '</strong><p>' + c.content + '</p></div>';
        });
        html += '<form id="rf-comment-form">'
          + '<input name="author_name" placeholder="Name" required>'
          + '<textarea name="content" placeholder="Comment" required></textarea>'
          + '<button type="submit">Post Comment</button>'
          + '</form>';
        document.getElementById('raisfast-comments').innerHTML = html;

        document.getElementById('rf-comment-form').addEventListener('submit', function(e) {
          e.preventDefault();
          fetch(apiBase + '/comments', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({
              post_id: postId,
              author_name: this.author_name.value,
              content: this.content.value,
            })
          }).then(function() { location.reload(); });
        });
      });
  })();
</script>
<% } %>

Include it in your article template:

<!-- layout/_partial/article.ejs, at the end -->
<%- partial('raisfast-comments') %>

Create a search partial at layout/_partial/raisfast-search.ejs:

<!-- layout/_partial/raisfast-search.ejs -->
<% if (config.raisfast && config.raisfast.enableSearch) { %>
<div id="raisfast-search">
  <input type="text" id="rf-search-input" placeholder="Search posts...">
  <div id="rf-search-results"></div>
</div>
<script>
  document.getElementById('rf-search-input').addEventListener('input', function() {
    if (this.value.length < 2) return;
    fetch('<%= config.raisfast.apiBase %>/search?q=' + encodeURIComponent(this.value))
      .then(function(r) { return r.json(); })
      .then(function(data) {
        document.getElementById('rf-search-results').innerHTML =
          data.data.items.map(function(p) {
            return '<a href="' + p.url + '">' + p.title + '</a><p>' + p.excerpt + '</p>';
          }).join('');
      });
  });
</script>
<% } %>

Step 5: Generate and Deploy

# Generate static files
hexo generate

# Preview locally (Hexo + RaisFast running together)
hexo server         # http://localhost:4000
raisfast             # http://localhost:9898

# Production deploy
hexo deploy          # Deploy to your static hosting
# Deploy RaisFast to the same server or a separate server

Nginx Config

server {
    listen 80;
    server_name yourdomain.com;

    # Hexo static files
    location / {
        root /var/www/hexo/public;
        try_files $uri $uri/ /index.html;
    }

    # RaisFast API
    location /api/ {
        proxy_pass http://127.0.0.1:9898;
    }
}

What's Next?

On this page