@autumnsgrove/groveengine
v0.8.0
Published
Multi-tenant blog engine for Grove Platform. Features gutter annotations, markdown editing, magic code auth, and Cloudflare Workers deployment.
Maintainers
Readme
Lattice (@autumnsgrove/groveengine)
Internal codename: GroveEngine
Multi-tenant blog engine for the Grove Platform. Each Grove site runs as its own Cloudflare Worker, powered by Lattice. A lattice is the framework that supports growth—vines climb it, gardens are built around it.
Features
- Gutter Annotations - Unique sidebar annotation system for blog posts
- Markdown Editor - Full-featured editor with live preview, themes, and drag-drop image upload
- Magic Code Auth - Passwordless authentication via email codes
- Admin Panel - Complete CMS for posts, pages, images, and settings
- Multi-Tenant Ready - Designed for username.grove.place architecture
- Cloudflare Native - D1 database, R2 storage, KV caching, Workers deployment
Architecture
Each Grove Site (Cloudflare Worker)
├── src/
│ ├── routes/
│ │ ├── admin/ # CMS admin panel
│ │ ├── api/ # REST API endpoints
│ │ ├── auth/ # Magic code authentication
│ │ ├── blog/ # Blog listing and posts
│ │ ├── about/ # Static about page
│ │ └── contact/ # Static contact page
│ └── lib/
│ ├── auth/ # JWT and session management
│ ├── components/ # Svelte components
│ │ ├── admin/ # MarkdownEditor, GutterManager
│ │ ├── custom/ # ContentWithGutter, TableOfContents
│ │ ├── gallery/ # ImageGallery, Lightbox, ZoomableImage
│ │ └── ui/ # shadcn-svelte components
│ ├── utils/ # Markdown parser, CSRF, sanitization
│ └── styles/ # CSS and tokens
├── UserContent/ # Site-specific content
├── migrations/ # D1 database migrations
└── static/fonts/ # Self-hosted fontsCloudflare Bindings Required
# wrangler.toml
[[d1_databases]]
binding = "DB"
database_name = "your-site-db"
database_id = "your-database-id"
[[r2_buckets]]
binding = "IMAGES"
bucket_name = "your-site-images"
[[kv_namespaces]]
binding = "CACHE"
id = "your-kv-id"Environment Variables
# .dev.vars
JWT_SECRET=your-secret-key
[email protected]
RESEND_API_KEY=re_xxxxxQuick Start
Clone and install
cd packages/engine npm installSet up Cloudflare resources
npx wrangler d1 create your-site-db npx wrangler r2 bucket create your-site-images npx wrangler kv:namespace create CACHERun migrations
npx wrangler d1 execute your-site-db --local --file=migrations/001_magic_codes.sql npx wrangler d1 execute your-site-db --local --file=migrations/002_auth_security.sql npx wrangler d1 execute your-site-db --local --file=migrations/003_site_settings.sql npx wrangler d1 execute your-site-db --local --file=migrations/004_pages_table.sql npx wrangler d1 execute your-site-db --local --file=migrations/005_multi_tenant.sqlConfigure environment
cp .dev.vars.example .dev.vars # Edit .dev.vars with your valuesStart development
npm run devDeploy
npx wrangler pages deploy
Fonts
Lattice includes self-hosted accessibility-focused fonts in static/fonts/. After installing the package, copy the fonts to your project's static directory:
# Copy fonts from node_modules to your static folder
cp -r node_modules/@autumnsgrove/groveengine/static/fonts/ static/fonts/Included fonts:
alagard.ttf- Pixel art styleAtkinsonHyperlegible-Regular.ttf- High legibilityCozetteVector.ttf- Bitmap styleCormorant-Regular.ttf- Elegant serifLexend-Regular.ttf- Reading optimizedOpenDyslexic-Regular.otf- Dyslexia-friendlyQuicksand-Regular.ttf- Rounded sans-serif
Your @font-face declarations should reference /fonts/fontname.ttf.
Key Components
Gutter System
The unique gutter annotation system allows sidebar notes on blog posts:
ContentWithGutter.svelte- Main content layoutGutterItem.svelte- Individual annotationsLeftGutter.svelte- Gutter containerGutterManager.svelte- Admin UI for managing gutters
Markdown Editor
Full-featured editor with:
- Live preview
- Multiple themes (Grove, Amber, Matrix, Dracula, Nord, Rose)
- Drag-drop image upload to R2
- Mermaid diagram support
- Slash commands
- Zen mode
Authentication
Passwordless magic code system:
- Email-based verification codes
- JWT sessions
- Rate limiting
- Constant-time comparison for security
Multi-Tenant Schema
The engine supports multi-tenant deployment where each tenant gets isolated data:
-- Each tenant (subdomain)
CREATE TABLE tenants (
id TEXT PRIMARY KEY,
subdomain TEXT UNIQUE NOT NULL,
plan TEXT DEFAULT 'starter',
-- ...
);
-- Posts scoped to tenant
CREATE TABLE posts (
id TEXT PRIMARY KEY,
tenant_id TEXT NOT NULL,
slug TEXT NOT NULL,
-- ...
UNIQUE(tenant_id, slug)
);Related Documentation
License
MIT
