2026-04-14 12:46:56 -04:00

Siteforge

This project is a React + TypeScript portfolio app built with Vite.

It is designed to showcase two categories of work:

  • Websites
  • Apps

The app now supports:

  • Dynamic cards generated from a project data source
  • Built vs Hosted filters
  • A dedicated About page route for each project
  • An admin editor route to update cards and About pages
  • A per-project README summary block on each project page
  • Embedded Spotify podcast player on the home section

Run locally

npm install
npm run dev:full

dev:full starts both:

  • Vite frontend (http://localhost:5173)
  • Admin content API (http://localhost:4173)

Build for production

npm run build

Run in container

Pull image directly:

docker pull ghcr.io/nmemmert/siteforge:latest
docker run -d --name siteforge-app -p 4173:4173 -v ./data:/app/data ghcr.io/nmemmert/siteforge:latest

Run with Docker Compose:

docker compose pull
docker compose up -d

Admin auth:

  • Set ADMIN_PASSWORD on the server/container to protect /admin and admin stats/maintenance endpoints.
  • Without ADMIN_PASSWORD, admin login is disabled until configured.

The app will be available at http://localhost:4173.

Optional local LLM (Ollama) for grounded rewrites

You can keep deterministic retrieval as the source-of-truth and optionally rewrite responses with a local model.

  1. Install and run Ollama on your host.
  2. Pull a small model suited to older hardware, for example:
ollama pull qwen2.5:3b-instruct
  1. Start the API with these environment variables:
CHATBOT_LLM_ENABLED=true
CHATBOT_LLM_BASE_URL=http://127.0.0.1:11434
CHATBOT_LLM_MODEL=qwen2.5:3b-instruct
CHATBOT_LLM_TIMEOUT_MS=25000
CHATBOT_LLM_NUM_CTX=2048
  1. Call the rewrite endpoint from your existing chat flow:

POST /api/chatbot-grounded-rewrite

Request payload shape:

{
	"question": "Who was Titus?",
	"draftAnswer": "Deterministic answer produced by current retrieval/synthesis.",
	"sources": ["Episode 2 - Introduction to Titus"],
	"contextChunks": [
		{
			"title": "Episode 2 - Introduction to Titus",
			"sourceLabel": "Episode 2",
			"content": "Titus was a Gentile..."
		}
	]
}

If the endpoint fails or is disabled, keep your deterministic answer and existing fallback behavior.

Persistent admin saves:

  • Admin updates are written to data/admin-content.json.
  • Built-in page hit stats are written to data/hit-stats.json.
  • Detailed visitor analytics are written to data/visitor-stats.json.
  • Backup snapshots are written to data/backups/.
  • docker-compose.yml mounts ./data into the container at /app/data.
  • This keeps all admin-managed data after container restarts/rebuilds/updates.

Where to edit content

  • Project domain data and ownership: src/data/projects.ts
  • Portfolio rendering logic: src/App.tsx
  • Portfolio UI styles: src/App.css
  • Global theme variables: src/index.css

Routes

  • Portfolio home: /
  • Project details: /projects/:slug
  • Admin editor: /admin

Admin editing

  • Open /admin to edit project card and featured-page content.
  • Use Global Settings to update theme, home headers, and quick tips.
  • Use Project Settings to update project-specific fields and README URL.
  • Use Create new entry to add a new project directly from Admin.
  • Enter a URL and click Scan URL metadata to auto-fill title, summary, domain, category, and icon when available.
  • Click Save project to apply updates instantly.
  • Saved edits are written to data/admin-content.json through the API server.
  • Built-in stats in /admin include page hits plus visitor details (IP, country/state/county/city, returning visitors, and recent visitor log).
  • Site Stats in /admin includes a Bible Questions inbox sourced from contact form submissions marked as Bible Question.
  • Analytics cookies are consent-based. Visitors can accept or decline tracking from the site banner.
  • Admin now includes maintenance actions: Export JSON, Backup Now, Prune Old Data, and Clear Analytics.
  • Admin also supports restoring from a backup snapshot from /admin.
  • The server creates startup + daily backup snapshots and retains recent backups automatically.
  • Use the Theme dropdown to switch between Sandstone, Ocean, Midnight, Forest, and Sunset.
  • Use Remove project to delete the selected project from your local Admin data.
  • Use Reset project or Reset all to restore defaults from src/data/projects.ts.

Scan notes:

  • URL scanning is best-effort and depends on site accessibility.
  • Some sites block direct scanning; Admin falls back to a proxy scan path when possible.
  • Always review scanned fields before saving.

Deployment note:

  • To keep Admin saves working on the internet, deploy with the Node API (server.js) and writable server storage for data/admin-content.json.

Useful container commands:

docker compose logs -f
docker compose down

Update to latest image:

docker compose pull
docker compose up -d

Notes

  • The current project cards are sample placeholders.
  • Most metadata was scanned from live pages.
  • Skywatch currently uses a manual fallback description due to a 401 response during automated scan.
S
Description
No description provided
Readme 31 MiB
Languages
TypeScript 47%
JavaScript 26.6%
CSS 15%
HTML 10.9%
Shell 0.4%