Skip to content

benthecoder/blog

Repository files navigation

Personal Blog

home

A minimalistic blog built with Next.js, React, and TypeScript. It uses Markdown for content and features search functionality powered by vector embeddings.

Design inspired by James Quiambao and Lee Robinson.

Features

  • Markdown-based blog posts with frontmatter
  • Dark/light mode support
  • Three types of search:
    • Keyword search (traditional text search)
    • Semantic search (using vector embeddings)
    • Hybrid search (combination of both)
  • RSS feed generation
  • Responsive design
  • Automated embedding generation via GitHub Actions

Development

To run the development server:

npm run dev

To build for production:

npm run build

Embedding Generation

Post content is processed into semantic embeddings using VoyageAI's embedding model. New embeddings are generated automatically via GitHub Actions when posts are added or updated.

To manually generate embeddings for a specific post:

npm run generate-embeddings [post-slug]

To generate embeddings for all posts:

npm run generate-embeddings

TODO

Improvements

New features

Inspirations

Setting up Planetscale for /thoughts page

brew install planetscale/tap/pscale
brew install mysql-client
pscale shell <DB_NAME> main

Run this to create table

CREATE TABLE tweets (
  id INT AUTO_INCREMENT PRIMARY KEY,
  content TEXT NOT NULL,
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

Setting up Neon for embedding search

Create pgvector extension

CREATE EXTENSION IF NOT EXISTS vector;
CREATE TABLE content_chunks (
    id UUID PRIMARY KEY,
    post_slug TEXT NOT NULL,
    post_title TEXT NOT NULL,
    content TEXT NOT NULL,
    chunk_type TEXT NOT NULL,
    metadata JSONB NOT NULL,
    sequence INTEGER NOT NULL,
    embedding vector(1024),
    created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);

-- Create a vector index for faster similarity search
CREATE INDEX ON content_chunks
USING ivfflat (embedding vector_cosine_ops)
WITH (lists = 100);

-- Create additional indexes for faster filtering
CREATE INDEX idx_content_chunks_post_slug ON content_chunks(post_slug);
CREATE INDEX idx_content_chunks_chunk_type ON content_chunks(chunk_type);

Run generate embeddings

npm run generate-embeddings