refactor: implement script tag approach for library inclusion
- Add script tags to demo-site HTML files for manual development - Disable CLI inline script injection to prevent duplicate scripts - Add library serving endpoints to servedev command - Update build process to auto-copy library to demo-site - Add CDN URL helpers for future production deployment - Update .gitignore for generated demo-site files Fixes .insertr-gate authentication for manual npm run serve workflow while maintaining clean separation between CLI and manual setups.
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -71,3 +71,6 @@ insertr-cli/build-errors.log
|
||||
|
||||
# Local development files
|
||||
.local/
|
||||
|
||||
# Demo site generated files
|
||||
demo-site/insertr.js
|
||||
@@ -1,76 +0,0 @@
|
||||
# Code Cleanup Summary
|
||||
|
||||
## Artifacts Removed from Architecture Pivot
|
||||
|
||||
### 🗑️ **Obsolete Assets Removed**
|
||||
- `insertr-cli/assets/editor/insertr-editor.js` - Legacy inline editor script
|
||||
- `insertr-cli/assets/editor/` directory - No longer needed
|
||||
- Unused `marked` npm dependency from root package.json
|
||||
|
||||
### 🧹 **Root Package.json Cleanup**
|
||||
**Before:**
|
||||
```json
|
||||
{
|
||||
"description": "Edit-in-place CMS for client websites - simple integration with class-based content editing",
|
||||
"main": "demo-site/insertr/insertr.js",
|
||||
"keywords": ["cms", "edit-in-place", "inline-editing", "client-websites", "go", "htmx", "alpine"],
|
||||
"dependencies": {
|
||||
"marked": "^16.2.1"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**After:**
|
||||
```json
|
||||
{
|
||||
"description": "The Tailwind of CMS - Zero-configuration content editing for any static site",
|
||||
"main": "lib/dist/insertr.js",
|
||||
"keywords": ["cms", "headless-cms", "static-site-generator", "build-time-enhancement", "zero-config", "go", "javascript"],
|
||||
"dependencies": {}
|
||||
}
|
||||
```
|
||||
|
||||
### ✅ **Legacy Code Preserved (Intentionally)**
|
||||
- `demo-site/archive/` - Contains original prototype for reference
|
||||
- `scripts/dev.js` - Still useful for testing original prototype
|
||||
- Legacy npm scripts (`dev:*`) - Kept for prototype development
|
||||
- `demo-site/README.md` - Accurately describes prototype functionality
|
||||
|
||||
### 🔧 **Enhanced .gitignore**
|
||||
Added new build artifacts:
|
||||
```gitignore
|
||||
# Build outputs
|
||||
lib/dist/ # Library build output
|
||||
insertr-cli/insertr # CLI executable
|
||||
insertr-cli/tmp/ # Air temporary files
|
||||
insertr-cli/build-errors.log # Air error logs
|
||||
```
|
||||
|
||||
### 🎯 **What Was NOT Removed**
|
||||
- **Archive directory**: `demo-site/archive/` kept for reference
|
||||
- **Development scripts**: Legacy scripts still work for prototype testing
|
||||
- **Documentation references**: Accurate historical context preserved
|
||||
- **Go embed assets**: `insertr-cli/pkg/content/assets/` must stay for embedding
|
||||
|
||||
## Validation
|
||||
|
||||
### ✅ **Build System Verified**
|
||||
```bash
|
||||
npm run build # ✅ Works
|
||||
cd insertr-cli && air # ✅ Hot reload works
|
||||
./insertr enhance # ✅ CLI works with embedded library
|
||||
```
|
||||
|
||||
### ✅ **Architecture Clean**
|
||||
- No dead code or unused imports in Go
|
||||
- No obsolete script references
|
||||
- Clean dependency tree (1 package removed)
|
||||
- Updated project metadata reflects current architecture
|
||||
|
||||
### 🎯 **Result**
|
||||
The codebase now cleanly separates:
|
||||
1. **Current Architecture**: `lib/` + `insertr-cli/` with proper embedding
|
||||
2. **Legacy Prototype**: `demo-site/archive/` for reference
|
||||
3. **Test Content**: `demo-site/` HTML files for enhancement testing
|
||||
|
||||
No functionality was lost, and the transition from prototype to production architecture is complete.
|
||||
215
DEVELOPMENT.md
215
DEVELOPMENT.md
@@ -1,215 +0,0 @@
|
||||
# Insertr Development Guide
|
||||
|
||||
## Quick Start
|
||||
|
||||
### Full-Stack Development (Recommended)
|
||||
1. **Install dependencies**:
|
||||
```bash
|
||||
npm install # Root project dependencies
|
||||
cd lib && npm install # Library dependencies
|
||||
```
|
||||
|
||||
2. **Start hot reload development**:
|
||||
```bash
|
||||
cd insertr-cli && air # Starts server with library hot reload
|
||||
```
|
||||
- Watches both Go CLI changes AND JavaScript library changes
|
||||
- Automatically rebuilds library → CLI → serves enhanced content
|
||||
- Visit http://localhost:3000 to see results
|
||||
|
||||
### Library-Only Development
|
||||
```bash
|
||||
cd lib && npm run watch # Just develop the JavaScript library
|
||||
```
|
||||
|
||||
### Legacy Frontend Development
|
||||
```bash
|
||||
npm run dev # Legacy live-server (demo-site only)
|
||||
```
|
||||
|
||||
## Development Workflow
|
||||
|
||||
### Hot Reload Development (Current Phase)
|
||||
|
||||
**🔥 NEW**: Full-stack hot reload with Air integration!
|
||||
|
||||
- **Library Source**: `lib/src/` - Independent JavaScript library
|
||||
- **CLI Integration**: `insertr-cli/` - Go CLI with embedded library
|
||||
- **Demo Site**: `demo-site/` - Test website for enhancement
|
||||
- **Automatic Rebuilds**: Changes to JS library trigger full rebuild cycle
|
||||
|
||||
#### How Hot Reload Works:
|
||||
1. Edit JavaScript in `lib/src/`
|
||||
2. Air detects changes → Rebuilds library → Copies to CLI → Rebuilds CLI
|
||||
3. Enhanced development server serves updated content
|
||||
4. Manual browser refresh shows changes
|
||||
|
||||
### Legacy Frontend Development
|
||||
|
||||
- **Demo Site**: `demo-site/` contains the prototype website
|
||||
- **Core Library**: `demo-site/insertr/insertr.js` - the old prototype library
|
||||
- **Mock API**: `demo-site/mock-api/content.json` - sample backend data structure
|
||||
|
||||
### Testing the Three User Types
|
||||
|
||||
1. **Customer View**: Open the site normally - clean, no edit interface
|
||||
2. **Client View**: Click "Login as Client" then "Edit Mode: On" - see edit buttons
|
||||
3. **Developer View**: Look at the HTML source to see simple integration
|
||||
|
||||
### Making Changes
|
||||
|
||||
#### Modern Development (lib/ + insertr-cli/)
|
||||
- **Library Changes**: Edit `lib/src/**/*.js` → Air automatically rebuilds everything
|
||||
- **CLI Changes**: Edit Go files in `insertr-cli/` → Air rebuilds and restarts server
|
||||
- **Demo Content**: Edit `demo-site/*.html` → Air serves enhanced versions
|
||||
- **Hot Reload**: Changes trigger full rebuild cycle (library → CLI → enhanced content)
|
||||
|
||||
#### Legacy Development (demo-site/)
|
||||
- **Live Reload**: The server automatically refreshes when you save changes
|
||||
- **JavaScript**: Edit `demo-site/insertr/insertr.js` for prototype functionality
|
||||
- **Content**: Edit HTML files to test different content structures
|
||||
|
||||
### Adding New Features
|
||||
|
||||
1. **Content Types**: Extend the `createEditForm()` method in insertr.js
|
||||
2. **UI Components**: Add new CSS classes and corresponding JavaScript
|
||||
3. **Authentication**: Modify the mock auth system in `toggleAuthentication()`
|
||||
|
||||
## Project Structure
|
||||
|
||||
```
|
||||
insertr/
|
||||
├── DEVELOPMENT.md # This file
|
||||
├── LIBRARY.md # Library architecture documentation
|
||||
├── package.json # Root project configuration
|
||||
│
|
||||
├── lib/ # 🆕 Independent JavaScript Library
|
||||
│ ├── src/
|
||||
│ │ ├── core/
|
||||
│ │ │ ├── insertr.js # Core library functionality
|
||||
│ │ │ ├── editor.js # Visual editing interface
|
||||
│ │ │ └── api-client.js # Content API client
|
||||
│ │ └── index.js # Library entry point
|
||||
│ ├── dist/
|
||||
│ │ ├── insertr.js # Built library (development)
|
||||
│ │ └── insertr.min.js # Built library (production)
|
||||
│ ├── package.json # Library dependencies
|
||||
│ └── rollup.config.js # Build configuration
|
||||
│
|
||||
├── insertr-cli/ # 🆕 Go CLI with Embedded Library
|
||||
│ ├── pkg/content/
|
||||
│ │ ├── assets/ # Embedded library files (auto-copied)
|
||||
│ │ ├── library.go # Go embed declarations
|
||||
│ │ ├── enhancer.go # HTML enhancement orchestrator
|
||||
│ │ ├── injector.go # Content injection logic
|
||||
│ │ └── ...
|
||||
│ ├── scripts/
|
||||
│ │ └── rebuild-library.sh # Air helper script
|
||||
│ ├── .air.toml # Hot reload configuration
|
||||
│ └── insertr # Built CLI executable
|
||||
│
|
||||
├── demo-site/ # Test website for enhancement
|
||||
│ ├── index.html # Demo homepage
|
||||
│ ├── about.html # Demo about page
|
||||
│ └── assets/style.css # Demo site styling
|
||||
│
|
||||
└── scripts/
|
||||
└── build.js # Integrated build script
|
||||
```
|
||||
|
||||
## Development Scripts
|
||||
|
||||
### Root Scripts
|
||||
- `npm run build` - Build library + CLI with embedded assets
|
||||
- `npm run dev` - Legacy live-server (demo-site only)
|
||||
|
||||
### Library Scripts (cd lib/)
|
||||
- `npm run build` - Build library to dist/
|
||||
- `npm run watch` - Watch and rebuild library on changes
|
||||
|
||||
### CLI Scripts (cd insertr-cli/)
|
||||
- `air` - 🔥 Hot reload server (library + CLI + enhanced content)
|
||||
- `go build -o insertr` - Manual CLI build
|
||||
- `./insertr enhance <dir>` - Enhance static site
|
||||
- `./insertr servedev <dir>` - Development server with enhancement
|
||||
|
||||
### Hot Reload Workflow
|
||||
```bash
|
||||
cd insertr-cli && air # Start hot reload development
|
||||
# Edit lib/src/**/*.js # Air detects → rebuilds → serves
|
||||
# Edit cmd/**/*.go # Air detects → rebuilds → serves
|
||||
# Edit ../demo-site/ # Air serves enhanced versions
|
||||
```
|
||||
|
||||
## Testing Different Scenarios
|
||||
|
||||
### Content Types
|
||||
- **Simple Text**: Logo, titles, short descriptions
|
||||
- **Rich Content**: Paragraphs with markdown, lists, links
|
||||
- **Mixed Content**: Cards with multiple editable sections
|
||||
|
||||
### User Flows
|
||||
1. **First Visit**: Customer sees clean site
|
||||
2. **Client Login**: Authentication state changes
|
||||
3. **Edit Mode**: Toggle editing interface
|
||||
4. **Content Editing**: Click edit → modify → save
|
||||
5. **Multi-page**: Test persistence across pages
|
||||
|
||||
### Browser Testing
|
||||
Test in different browsers to ensure compatibility:
|
||||
- Chrome/Edge (Chromium)
|
||||
- Firefox
|
||||
- Safari (if on macOS)
|
||||
|
||||
## Future Development Phases
|
||||
|
||||
### Phase 2: Backend Integration
|
||||
- Go HTTP server with REST API
|
||||
- Real authentication with Authentik OAuth
|
||||
- File-based content persistence
|
||||
- Git version control
|
||||
|
||||
### Phase 3: Production Features
|
||||
- Multi-tenant support
|
||||
- Admin dashboard
|
||||
- Content validation
|
||||
- Image upload
|
||||
- Deployment automation
|
||||
|
||||
## Contributing Guidelines
|
||||
|
||||
1. **Make changes** in small, focused commits
|
||||
2. **Test thoroughly** across different content types
|
||||
3. **Update documentation** when adding new features
|
||||
4. **Follow existing code style** and patterns
|
||||
|
||||
## Debugging Tips
|
||||
|
||||
### JavaScript Console
|
||||
- Open browser dev tools (F12)
|
||||
- Check for errors in Console tab
|
||||
- Use `window.insertr` to inspect library state
|
||||
|
||||
### Local Storage
|
||||
- View saved content: `localStorage.getItem('insertr_content')`
|
||||
- Clear saved content: `localStorage.clear()`
|
||||
|
||||
### Network Simulation
|
||||
- The library simulates network delays and occasional failures
|
||||
- Check browser Network tab to see mock API calls (when implemented)
|
||||
|
||||
## Common Issues
|
||||
|
||||
### Live Server Not Working
|
||||
- Ensure port 3000 is available
|
||||
- Try different port: `live-server demo-site --port=3001`
|
||||
|
||||
### Changes Not Reflecting
|
||||
- Hard refresh browser (Ctrl+F5 / Cmd+Shift+R)
|
||||
- Check browser cache settings
|
||||
- Verify file paths are correct
|
||||
|
||||
### Edit Buttons Not Showing
|
||||
- Check authentication state (click "Login as Client")
|
||||
- Enable edit mode (click "Edit Mode: Off" → "Edit Mode: On")
|
||||
- Verify elements have `class="insertr"` and `data-content-id`
|
||||
@@ -1,39 +0,0 @@
|
||||
# Insertr Development Quickstart
|
||||
|
||||
## Project Structure
|
||||
|
||||
- `lib/` - JavaScript library development (all Node.js tooling)
|
||||
- `insertr-cli/` - Go CLI application
|
||||
- `demo-site/` - Static HTML demo site
|
||||
|
||||
## Getting Started
|
||||
|
||||
### Library Development
|
||||
```bash
|
||||
cd lib/
|
||||
npm install
|
||||
npm run serve # Start development server
|
||||
npm run check # Validate setup
|
||||
npm run demo # Show demo instructions
|
||||
```
|
||||
|
||||
### CLI Development
|
||||
```bash
|
||||
cd insertr-cli/
|
||||
air # Hot reload development server
|
||||
```
|
||||
|
||||
### Build Everything
|
||||
```bash
|
||||
cd lib/
|
||||
npm run build:all # Builds library + CLI with embedded assets
|
||||
```
|
||||
|
||||
## Architecture
|
||||
|
||||
The CLI embeds the JavaScript library at build time for distribution. During development:
|
||||
- `lib/` contains the JavaScript library source and build tools
|
||||
- Air (Go hot reload) watches `lib/src/` and rebuilds when library changes
|
||||
- Demo site served from `lib/` package for unified development experience
|
||||
|
||||
All Node.js dependencies and scripts are now consolidated in the `lib/` package.
|
||||
98
INITIAL.md
98
INITIAL.md
@@ -1,98 +0,0 @@
|
||||
# Insertr
|
||||
A content management system for client websites.
|
||||
|
||||
I host a few client services and static web-sites and I want to integrate content management for the client. They should be able to change the content of the site, if not the layout. I am open to hearing about existing solutions, but I am considering building my own. If I were to build my own CMS I imagine an edit-in-place experience - probably with Go on the backend and something like htmx/alpine on the front-end, although I would be open for other alternatives.
|
||||
|
||||
## Features / User stories
|
||||
This list is not exhaustive and will be expanded as we research.
|
||||
|
||||
### Users
|
||||
This application have to keep three types of users in mind.
|
||||
- *The developer* - Creating web-sites or services for small businisses
|
||||
- *The client* - The one in daily control of the content. Sign in - make changes - see outcome. A simple system for any tech-litteracy level. "Update however and whenever you will, without involving tech support."
|
||||
- *The customer* - Client's customers who will view and consume the site or service.
|
||||
|
||||
### MVP
|
||||
- [ ] Client should sign in through a SSO (I am hosting an authentik instance that should manage users through oAuth).
|
||||
- [ ] See the public-facing version of their page, but with an edit button in the top right corner of "content components". If they click the button the content will be replaced with a form coresponding to the component's content, rendered in markdown. They can edit the content and submit/save their changes.
|
||||
- [ ] This will trigger an update of the content on the server.
|
||||
|
||||
If I were to write a wish list it would be:
|
||||
- [ ] Slapp a class on a div: <div class="insertr"> | <div insetr>, and it works.
|
||||
|
||||
## Research Results (Completed)
|
||||
|
||||
### Existing Solutions Analysis
|
||||
- **TinaCMS**: Git-based with visual editing, but requires Next.js/React framework
|
||||
- **Strapi**: Full headless CMS, complex setup, Node.js based
|
||||
- **Contentful**: Commercial solution, API-based, not self-hosted
|
||||
- **Ghost**: Publishing-focused, not suitable for general content management
|
||||
- **Conclusion**: No existing solution offers the simple "add a class and it works" approach
|
||||
|
||||
### Tech Stack Decision: Go + htmx/Alpine
|
||||
**Rationale:**
|
||||
- **Go**: Fast, single binary deployment, excellent web server performance
|
||||
- **htmx**: Perfect for edit-in-place with partial page updates
|
||||
- **Alpine.js**: Lightweight reactive behaviors without framework complexity
|
||||
- **Architecture**: Dynamic (not static site generation) for real-time editing
|
||||
|
||||
### Authentication Integration
|
||||
- **Authentik OAuth 2.0**: Standard flow for client authentication
|
||||
- **JWT tokens**: For API authorization and session management
|
||||
- **Multi-tenant**: Role-based access per site/content section
|
||||
|
||||
## Prototype Roadmap
|
||||
|
||||
### Phase 1: Frontend Proof-of-Concept
|
||||
**Goal**: Demonstrate edit-in-place functionality with mock data
|
||||
**Deliverables**:
|
||||
- [ ] Demo business website (Acme Consulting example)
|
||||
- [ ] insertr.js library with core functionality
|
||||
- [ ] Three user view modes (Customer/Client/Developer)
|
||||
- [ ] Mock authentication flow
|
||||
- [ ] Inline editing with markdown support
|
||||
|
||||
### Phase 2: Backend Integration
|
||||
**Goal**: Connect to Go server with real data persistence
|
||||
**Deliverables**:
|
||||
- [ ] Go HTTP server with REST API
|
||||
- [ ] File-based content storage
|
||||
- [ ] Authentik OAuth integration
|
||||
- [ ] Git-based version control
|
||||
|
||||
### Phase 3: Production Features
|
||||
**Goal**: Multi-tenant deployment ready system
|
||||
**Deliverables**:
|
||||
- [ ] Admin dashboard
|
||||
- [ ] Content validation and security
|
||||
- [ ] Deployment automation
|
||||
- [ ] Documentation and examples
|
||||
|
||||
## User Experience Design
|
||||
|
||||
### The Customer (End User)
|
||||
- Clean website experience with no edit interface
|
||||
- Fast loading, no unnecessary JavaScript
|
||||
|
||||
### The Client (Content Manager)
|
||||
- Same website + subtle edit indicators (✏️ icons)
|
||||
- Click to edit → inline form → save/cancel
|
||||
- Markdown editing for rich content
|
||||
- Immediate visual feedback
|
||||
|
||||
### The Developer (Integration)
|
||||
```html
|
||||
<!-- Simple integration -->
|
||||
<script src="https://insertr.example.com/insertr.js"></script>
|
||||
<div class="insertr" data-content-id="hero">
|
||||
<h1>Editable Content</h1>
|
||||
</div>
|
||||
```
|
||||
|
||||
## Next Immediate Steps
|
||||
1. Create demo website mockup
|
||||
2. Build core insertr.js library
|
||||
3. Implement edit-in-place UI
|
||||
4. Add mock authentication flow
|
||||
5. Test with multiple content types
|
||||
|
||||
138
LIBRARY.md
138
LIBRARY.md
@@ -1,138 +0,0 @@
|
||||
# Insertr Library Architecture
|
||||
|
||||
## Overview
|
||||
|
||||
Insertr now uses a proper separation between the JavaScript library and Go CLI, following the "Tailwind of CMS" philosophy where the library can be developed independently and embedded into the CLI at build time.
|
||||
|
||||
## Project Structure
|
||||
|
||||
```
|
||||
insertr/
|
||||
├── lib/ # Independent JavaScript library
|
||||
│ ├── src/
|
||||
│ │ ├── core/
|
||||
│ │ │ ├── insertr.js # Main library core
|
||||
│ │ │ ├── editor.js # Visual editing functionality
|
||||
│ │ │ └── api-client.js # Content API client
|
||||
│ │ └── index.js # Library entry point
|
||||
│ ├── dist/
|
||||
│ │ ├── insertr.js # Built library (dev)
|
||||
│ │ └── insertr.min.js # Built library (production)
|
||||
│ ├── package.json
|
||||
│ └── rollup.config.js # Build configuration
|
||||
├── insertr-cli/ # Go CLI with embedded library
|
||||
│ ├── pkg/content/
|
||||
│ │ ├── assets/ # Embedded library files
|
||||
│ │ │ ├── insertr.js # From lib/dist/
|
||||
│ │ │ └── insertr.min.js # From lib/dist/
|
||||
│ │ ├── library.go # Go embed declarations
|
||||
│ │ ├── injector.go # HTML injection logic
|
||||
│ │ └── ...
|
||||
│ └── insertr # Built CLI executable
|
||||
└── scripts/
|
||||
└── build.js # Integrated build script
|
||||
```
|
||||
|
||||
## Build Process
|
||||
|
||||
### 1. Library Development (`lib/`)
|
||||
```bash
|
||||
cd lib
|
||||
npm install
|
||||
npm run build # Creates dist/insertr.js and dist/insertr.min.js
|
||||
npm run watch # Development mode with file watching
|
||||
```
|
||||
|
||||
### 2. CLI Integration (`insertr-cli/`)
|
||||
The CLI uses Go's `//go:embed` directive to embed the built library:
|
||||
|
||||
```go
|
||||
//go:embed assets/insertr.min.js
|
||||
var libraryMinJS string
|
||||
|
||||
//go:embed assets/insertr.js
|
||||
var libraryJS string
|
||||
```
|
||||
|
||||
### 3. Integrated Build (Root)
|
||||
```bash
|
||||
npm run build # Builds both library AND CLI with embedded assets
|
||||
```
|
||||
|
||||
This script:
|
||||
1. Builds the JavaScript library (`lib/dist/`)
|
||||
2. Copies built assets to CLI (`insertr-cli/pkg/content/assets/`)
|
||||
3. Builds Go CLI with embedded library
|
||||
|
||||
## Library Features
|
||||
|
||||
### Core Functionality (`src/core/insertr.js`)
|
||||
- Element discovery: `findEnhancedElements()`
|
||||
- Metadata extraction: `getElementMetadata()`
|
||||
- Element management: `getAllElements()`
|
||||
|
||||
### Visual Editor (`src/core/editor.js`)
|
||||
- Hover effects and visual indicators
|
||||
- Click-to-edit functionality
|
||||
- Content update handling
|
||||
- Dynamic style injection
|
||||
|
||||
### API Client (`src/core/api-client.js`)
|
||||
- RESTful content API communication
|
||||
- CRUD operations for content
|
||||
- Error handling and fallbacks
|
||||
|
||||
## CLI Integration
|
||||
|
||||
### Asset Embedding (`pkg/content/library.go`)
|
||||
```go
|
||||
func GetLibraryScript(minified bool) string {
|
||||
if minified {
|
||||
return libraryMinJS // Production: smaller file size
|
||||
}
|
||||
return libraryJS // Development: readable code
|
||||
}
|
||||
```
|
||||
|
||||
### HTML Injection (`pkg/content/injector.go`)
|
||||
```go
|
||||
func (i *Injector) InjectEditorAssets(doc *html.Node, isDevelopment bool, libraryScript string) {
|
||||
// Injects the embedded library as inline <script> tag
|
||||
}
|
||||
```
|
||||
|
||||
## Development Workflow
|
||||
|
||||
### Library Development
|
||||
```bash
|
||||
cd lib
|
||||
npm run watch # Auto-rebuild on changes
|
||||
```
|
||||
|
||||
### CLI Development
|
||||
```bash
|
||||
cd insertr-cli
|
||||
go build -o insertr
|
||||
./insertr enhance ../demo-site/
|
||||
```
|
||||
|
||||
### Full Integration Testing
|
||||
```bash
|
||||
npm run build # Builds library + CLI
|
||||
cd insertr-cli && ./insertr enhance ../demo-site/
|
||||
```
|
||||
|
||||
## Benefits
|
||||
|
||||
1. **Independent Development**: Library can be developed and tested separately
|
||||
2. **Version Control**: CLI embeds specific library version at build time
|
||||
3. **Zero Dependencies**: Enhanced HTML contains everything needed to run
|
||||
4. **CDN Ready**: Library can be served from CDN in production
|
||||
5. **Development Friendly**: Unminified version for debugging
|
||||
|
||||
## Future Enhancements
|
||||
|
||||
- **CDN Integration**: Support for `<script src="https://cdn.insertr.dev/v1.0.0/insertr.min.js">`
|
||||
- **Library Hot Reload**: Auto-rebuild CLI when library changes
|
||||
- **Version Sync**: Automated version bumping across library and CLI
|
||||
- **Production Optimization**: Tree-shaking and custom builds
|
||||
682
RESEARCH.md
682
RESEARCH.md
@@ -1,682 +0,0 @@
|
||||
# CMS Approaches and Workflows: Comprehensive Research
|
||||
|
||||
## Executive Summary
|
||||
|
||||
This document analyzes different Content Management System (CMS) approaches, their workflows, and architectural patterns to inform the strategic direction of Insertr CMS. Through extensive research and strategic iteration, we've identified a unique positioning as "The Tailwind of CMS" - an HTML enhancement service that adds editing capabilities to any static site without architectural changes.
|
||||
|
||||
## Table of Contents
|
||||
|
||||
1. [CMS Architecture Patterns](#cms-architecture-patterns)
|
||||
2. [Content Workflow Analysis](#content-workflow-analysis)
|
||||
3. [Rebuild Strategy Comparison](#rebuild-strategy-comparison)
|
||||
4. [Strategic Pivot: HTML Enhancement Approach](#strategic-pivot-html-enhancement-approach)
|
||||
5. [Competitive Landscape](#competitive-landscape)
|
||||
6. [Market Positioning: "The Tailwind of CMS"](#market-positioning-the-tailwind-of-cms)
|
||||
7. [Technical Implementation](#technical-implementation)
|
||||
8. [Strategic Recommendations](#strategic-recommendations)
|
||||
|
||||
---
|
||||
|
||||
## CMS Architecture Patterns
|
||||
|
||||
### 1. Traditional CMS (WordPress, Drupal)
|
||||
**Architecture**: Monolithic, database-driven, server-side rendering
|
||||
**Content Flow**: Database → Server → HTML → Browser
|
||||
**Deployment**: Server hosting, automatic updates, runtime content changes
|
||||
|
||||
**Pros:**
|
||||
- Immediate content updates
|
||||
- Rich ecosystem of plugins/themes
|
||||
- Non-technical user friendly
|
||||
- Mature tooling and community
|
||||
|
||||
**Cons:**
|
||||
- Security vulnerabilities
|
||||
- Performance bottlenecks
|
||||
- Server maintenance overhead
|
||||
- Vendor lock-in to hosting stack
|
||||
|
||||
**Example Workflow:**
|
||||
```
|
||||
Editor → WordPress Admin → Database → Live Site
|
||||
(Immediate, no build process)
|
||||
```
|
||||
|
||||
### 2. Headless/API-First CMS (Contentful, Strapi, Sanity)
|
||||
**Architecture**: API backend + Frontend application
|
||||
**Content Flow**: API Database → GraphQL/REST → Static Build/Runtime → Browser
|
||||
**Deployment**: Separate API server + Static/Dynamic frontend
|
||||
|
||||
**Pros:**
|
||||
- Flexible frontend technology choices
|
||||
- Scalable API architecture
|
||||
- Multi-channel content delivery
|
||||
- Developer-friendly GraphQL/REST APIs
|
||||
|
||||
**Cons:**
|
||||
- Complex setup and configuration
|
||||
- API dependency for content
|
||||
- Runtime performance considerations
|
||||
- Higher technical complexity
|
||||
|
||||
**Example Workflow:**
|
||||
```
|
||||
Editor → Headless CMS Admin → API → Webhook → Build Process → Static Site
|
||||
(Build-dependent, but flexible)
|
||||
```
|
||||
|
||||
### 3. Git-Based CMS (Decap, Forestry, CloudCannon, TinaCMS)
|
||||
**Architecture**: Git repository as content database + Admin interface
|
||||
**Content Flow**: Git Files → Admin UI → Git Commits → Static Site Generator → Browser
|
||||
**Deployment**: Git-triggered builds, static site deployment
|
||||
|
||||
**Pros:**
|
||||
- Version control for content
|
||||
- Developer-friendly Git workflow
|
||||
- Static site performance benefits
|
||||
- Backup and rollback capabilities
|
||||
|
||||
**Cons:**
|
||||
- Rebuild requirements for changes
|
||||
- Git complexity for non-technical users
|
||||
- Limited real-time collaboration
|
||||
- Build time delays
|
||||
- **File mapping complexity**
|
||||
|
||||
**Example Workflow:**
|
||||
```
|
||||
Editor → Git-based Admin → Git Commit → Build Trigger → Static Site
|
||||
(Git-dependent, build-required)
|
||||
```
|
||||
|
||||
### 4. Visual/Page Builder CMS (Webflow, Wix, Builder.io)
|
||||
**Architecture**: Visual interface + Hosted rendering engine
|
||||
**Content Flow**: Visual Editor → Proprietary Database → Rendered Pages → Browser
|
||||
**Deployment**: Platform-hosted, automatic deployment
|
||||
|
||||
**Pros:**
|
||||
- No-code visual editing
|
||||
- Immediate visual feedback
|
||||
- Built-in hosting and optimization
|
||||
- Designer-friendly interface
|
||||
|
||||
**Cons:**
|
||||
- Vendor lock-in
|
||||
- Limited customization depth
|
||||
- Export/migration difficulties
|
||||
- Higher costs for custom needs
|
||||
|
||||
### 5. **HTML Enhancement Pattern (Insertr's Approach)**
|
||||
**Architecture**: Build-time content injection + Conditional editor loading
|
||||
**Content Flow**: Static HTML → Enhancement CLI → Database Content → Enhanced Site
|
||||
**Deployment**: Standard static site deployment with editing capabilities
|
||||
|
||||
**Pros:**
|
||||
- Zero runtime overhead for visitors
|
||||
- Works with any static site generator
|
||||
- No architectural changes required
|
||||
- Database-backed content storage
|
||||
- Framework-agnostic approach
|
||||
|
||||
**Cons:**
|
||||
- Build-dependent for content updates
|
||||
- Requires enhancement step in build process
|
||||
|
||||
**Example Workflow:**
|
||||
```
|
||||
Static Site Build → Insertr Enhancement CLI → Enhanced HTML → Deploy
|
||||
↓
|
||||
Database Content Injection + Editor Loading
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Content Workflow Analysis
|
||||
|
||||
### Immediate Update Pattern
|
||||
**Used by**: WordPress, Webflow, Traditional CMS
|
||||
**Flow**: Edit → Save → Live (0-5 seconds)
|
||||
**Benefits**: Instant feedback, simple mental model
|
||||
**Drawbacks**: No review process, potential for mistakes
|
||||
|
||||
### Build-Dependent Pattern
|
||||
**Used by**: Gatsby + Contentful, Decap CMS, Hugo workflows
|
||||
**Flow**: Edit → Save → Build → Deploy (2-10 minutes)
|
||||
**Benefits**: Review process, optimized output, version control
|
||||
**Drawbacks**: Slow feedback loop, build complexity
|
||||
|
||||
### Enhancement Pattern (Insertr's Approach)
|
||||
**Flow**: Edit (cached) → Batch Publish → Enhanced Rebuild → Deploy
|
||||
**Benefits**:
|
||||
- Static performance for visitors
|
||||
- Rich editing experience for editors
|
||||
- Batched updates reduce build frequency
|
||||
- Zero configuration required
|
||||
**Drawbacks**: 2-5 minute delay for content changes to go live
|
||||
|
||||
---
|
||||
|
||||
## Rebuild Strategy Comparison
|
||||
|
||||
### The "Decap Problem": Every Edit Triggers Rebuild
|
||||
**Issue**: Each content change commits to Git → triggers full site rebuild
|
||||
**Impact**:
|
||||
- Slow feedback (2-10 minute delays)
|
||||
- Expensive build resources
|
||||
- Poor user experience for iterative editing
|
||||
- CI/CD queue bottlenecks
|
||||
- **File mapping configuration complexity**
|
||||
|
||||
### Insertr's Solution: Build-Time Enhancement
|
||||
**Strategy**:
|
||||
1. Static site builds normally (Hugo, Next.js, etc.)
|
||||
2. Enhancement CLI reads built HTML + fetches latest content
|
||||
3. CLI injects current content into HTML + adds editing hooks
|
||||
4. Deploy enhanced static site
|
||||
5. Editors trigger batched rebuilds only when publishing
|
||||
|
||||
**Benefits**:
|
||||
- Eliminates file mapping complexity
|
||||
- Reduces rebuild frequency through batching
|
||||
- Maintains pure static performance
|
||||
- Works with any SSG without configuration
|
||||
|
||||
---
|
||||
|
||||
## Strategic Pivot: HTML Enhancement Approach
|
||||
|
||||
### Core Insight: Avoid File/Git Mapping Complexity
|
||||
|
||||
**Problem with Git-Based Approach**:
|
||||
- Mapping `data-content-id` to files/fields requires configuration
|
||||
- Different SSGs have different file conventions
|
||||
- Merge conflicts in collaborative editing
|
||||
- Schema drift as files change
|
||||
- Framework coupling issues
|
||||
|
||||
**Solution: Database + Build-Time Injection**:
|
||||
- Simple key-value storage: `content_id → content_value`
|
||||
- No file mapping needed
|
||||
- Framework agnostic
|
||||
- Conflict-free collaborative editing
|
||||
- Audit trails and change tracking
|
||||
|
||||
### New Architecture: "Editing as a Service"
|
||||
|
||||
```
|
||||
┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐
|
||||
│ Static Site │ │ Enhancement CLI │ │ Enhanced │
|
||||
│ Generator │ │ │ │ Deployment │
|
||||
│ │ │ │ │ │
|
||||
│ Hugo/Next.js/ │───▶│ Parse HTML │───▶│ Static Site │
|
||||
│ Jekyll/etc. │ │ Inject Content │ │ + Editing │
|
||||
│ │ │ Add Editor Hooks │ │ + Smart Loading │
|
||||
│ Outputs: │ │ │ │ │
|
||||
│ Pure HTML │ │ Database ←→ API │ │ Zero Overhead │
|
||||
└─────────────────┘ └──────────────────┘ └─────────────────┘
|
||||
```
|
||||
|
||||
### GitHub Actions Integration Example
|
||||
|
||||
```yaml
|
||||
# .github/workflows/deploy.yml
|
||||
name: Build and Deploy
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
# 1. Standard static site build
|
||||
- uses: actions/checkout@v3
|
||||
- name: Build static site
|
||||
run: hugo --minify
|
||||
|
||||
# 2. Enhance with Insertr
|
||||
- name: Add editing capabilities
|
||||
run: npx @insertr/enhance ./public --output ./dist --api-url ${{ secrets.INSERTR_API_URL }}
|
||||
|
||||
# 3. Deploy enhanced site
|
||||
- name: Deploy to GitHub Pages
|
||||
uses: peaceiris/actions-gh-pages@v3
|
||||
with:
|
||||
publish_dir: ./dist
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Competitive Landscape
|
||||
|
||||
### Market Leaders Analysis
|
||||
|
||||
#### CloudCannon
|
||||
**Position**: Enterprise Git-based CMS
|
||||
**Strengths**:
|
||||
- Mature visual editing
|
||||
- Multi-SSG support
|
||||
- Agency-focused features
|
||||
- Robust hosting integration
|
||||
|
||||
**Weaknesses**:
|
||||
- Complex setup process (days of configuration)
|
||||
- Expensive pricing model ($45+/month)
|
||||
- Opinionated workflow requirements
|
||||
- Heavy platform lock-in
|
||||
- Component-based editing only
|
||||
|
||||
**Target Market**: Digital agencies, enterprise teams, complex multi-site setups
|
||||
|
||||
#### TinaCMS
|
||||
**Position**: Git + API hybrid, developer-friendly
|
||||
**Strengths**:
|
||||
- React-based editing
|
||||
- Git workflow with API preview
|
||||
- Open source with cloud offering
|
||||
- Developer-centric approach
|
||||
|
||||
**Weaknesses**:
|
||||
- React/Next.js focused (limited framework support)
|
||||
- Still requires significant setup
|
||||
- Complex architecture
|
||||
- Schema configuration required
|
||||
|
||||
**Target Market**: React developers, Next.js sites, developer-first teams
|
||||
|
||||
#### Decap CMS (formerly Netlify CMS)
|
||||
**Position**: Simple Git-based editing
|
||||
**Strengths**:
|
||||
- Easy setup
|
||||
- Framework agnostic
|
||||
- Open source
|
||||
- Simple mental model
|
||||
|
||||
**Weaknesses**:
|
||||
- Poor editing UX (form-based)
|
||||
- Constant rebuild issue
|
||||
- Limited customization
|
||||
- Maintenance mode concerns
|
||||
|
||||
**Target Market**: Individual developers, simple blogs, basic static sites
|
||||
|
||||
### Market Gap Analysis
|
||||
|
||||
#### Under-Served Segments:
|
||||
1. **Existing Static Sites**: Need editing without architectural changes
|
||||
2. **Budget-Conscious Developers**: Need CMS features without enterprise costs
|
||||
3. **Framework-Agnostic Teams**: Want editing that works with any tech stack
|
||||
4. **Rapid Integration**: Need editing capabilities added in minutes, not days
|
||||
5. **Element-Level Editing**: Granular control over specific content elements
|
||||
|
||||
---
|
||||
|
||||
## Market Positioning: "The Tailwind of CMS"
|
||||
|
||||
### Philosophy Parallel
|
||||
|
||||
**Tailwind CSS Approach**:
|
||||
- Utility-first classes: `class="text-lg font-bold"`
|
||||
- Build-time optimization (PurgeCSS)
|
||||
- Framework agnostic
|
||||
- Developer workflow integration
|
||||
- Zero runtime overhead
|
||||
|
||||
**Insertr CMS Approach**:
|
||||
- Content-first classes: `class="insertr"`
|
||||
- Build-time enhancement (content injection)
|
||||
- Framework agnostic
|
||||
- Developer workflow integration
|
||||
- Zero runtime overhead for visitors
|
||||
|
||||
### Shared Principles
|
||||
|
||||
#### 1. Zero Configuration Philosophy
|
||||
**Tailwind**: No CSS files, everything in HTML
|
||||
**Insertr**: No schema files, everything in HTML markup
|
||||
|
||||
#### 2. Build-Time Optimization
|
||||
**Tailwind**: Unused styles purged at build time
|
||||
**Insertr**: Content injected and editor bundled at build time
|
||||
|
||||
#### 3. Developer Experience Focus
|
||||
**Tailwind**: Stay in markup, don't context switch to CSS files
|
||||
**Insertr**: Stay in markup, don't context switch to CMS admin panels
|
||||
|
||||
#### 4. Framework Agnostic
|
||||
**Tailwind**: Works with React, Vue, vanilla HTML, etc.
|
||||
**Insertr**: Works with Hugo, Next.js, Jekyll, etc.
|
||||
|
||||
### Value Propositions
|
||||
|
||||
#### For Developers:
|
||||
- **"Rapidly add editing to any website without ever leaving your markup"**
|
||||
- 5-minute setup vs days of CMS configuration
|
||||
- Works with existing design systems and frameworks
|
||||
- No architectural changes required
|
||||
|
||||
#### For Content Editors:
|
||||
- Edit content directly on the live site
|
||||
- No forms, no admin panels - just click and edit
|
||||
- See changes exactly as visitors will
|
||||
|
||||
#### For Agencies:
|
||||
- Turn any static site into an editable website for clients
|
||||
- No CMS migration needed - enhance existing sites
|
||||
- Client-friendly editing without developer complexity
|
||||
|
||||
---
|
||||
|
||||
## Technical Implementation
|
||||
|
||||
### Auto-Generated Content IDs
|
||||
|
||||
**Problem**: Manual `data-content-id` adds friction
|
||||
**Solution**: Automatic ID generation at build time
|
||||
|
||||
**Developer Writes**:
|
||||
```html
|
||||
<h1 class="insertr">Welcome to Our Site</h1>
|
||||
<p class="insertr">This is editable content</p>
|
||||
```
|
||||
|
||||
**Enhancement CLI Generates**:
|
||||
```html
|
||||
<h1 class="insertr" data-content-id="hero-welcome-title">
|
||||
Latest Title From Database
|
||||
</h1>
|
||||
<p class="insertr" data-content-id="hero-description">
|
||||
Latest Description From Database
|
||||
</p>
|
||||
```
|
||||
|
||||
### Smart Loading for Performance
|
||||
|
||||
**For Regular Visitors (99% of traffic)**:
|
||||
- Zero editor assets loaded
|
||||
- Pure static HTML performance
|
||||
- Tiny auth check (~1KB)
|
||||
|
||||
**For Authenticated Editors**:
|
||||
- Rich editing UI loads on demand
|
||||
- Full feature set available
|
||||
- Real-time editing experience
|
||||
|
||||
```javascript
|
||||
// Only load editor for authenticated users
|
||||
if (await insertr.isAuthenticated()) {
|
||||
await insertr.loadEditor();
|
||||
insertr.activateEditing();
|
||||
}
|
||||
// Otherwise: zero overhead
|
||||
```
|
||||
|
||||
### Content Storage Architecture
|
||||
|
||||
**Simple Database Model**:
|
||||
```sql
|
||||
CREATE TABLE content (
|
||||
id SERIAL PRIMARY KEY,
|
||||
content_id VARCHAR(255) UNIQUE NOT NULL,
|
||||
site_id VARCHAR(255) NOT NULL,
|
||||
value TEXT NOT NULL,
|
||||
type VARCHAR(50) NOT NULL DEFAULT 'text',
|
||||
updated_at TIMESTAMP DEFAULT NOW()
|
||||
);
|
||||
```
|
||||
|
||||
**No File Mapping Required**:
|
||||
- Direct content_id → value lookup
|
||||
- No configuration files needed
|
||||
- Framework agnostic storage
|
||||
- Simple API: GET/PUT `/api/content/:id`
|
||||
|
||||
---
|
||||
|
||||
## Content ID Generation Strategy
|
||||
|
||||
### Philosophy: Zero Configuration with Pragmatic Stability
|
||||
|
||||
**Core Principle**: Developers should never think about content IDs unless they choose to.
|
||||
|
||||
#### Two-Phase Approach
|
||||
|
||||
**Development Phase (Pre-Production):**
|
||||
- IDs are **completely disposable** and can change freely
|
||||
- Generated using: `context-tag-hash` (e.g., `hero-h1-abc123ef`)
|
||||
- Developers focus purely on markup: `<h1 class="insertr">Title</h1>`
|
||||
- Only use HTML `id` attributes for complex stability requirements
|
||||
|
||||
**Production Phase (Post-Launch):**
|
||||
- Preserve existing content mappings for stability
|
||||
- CLI detects structural changes and warns about orphaned content
|
||||
- Simple migration prompts for major refactoring
|
||||
- Database tracks content lifecycle with "last seen" timestamps
|
||||
|
||||
#### ID Generation Algorithm
|
||||
|
||||
```go
|
||||
func generateContentID(element) string {
|
||||
context := nearestContext(element) // From HTML id or DOM position
|
||||
tag := element.Tag // h1, p, button
|
||||
hash := structureHash(element)[:8] // Element structure, not content
|
||||
|
||||
return fmt.Sprintf("%s-%s-%s", context, tag, hash)
|
||||
}
|
||||
```
|
||||
|
||||
**Context Resolution Priority:**
|
||||
1. Nearest parent with HTML `id` attribute
|
||||
2. Semantic section detection (header, main, aside, etc.)
|
||||
3. DOM position fallback (section-0, div-1, etc.)
|
||||
|
||||
#### Edge Cases and Solutions
|
||||
|
||||
**1. Content Lifecycle Issues**
|
||||
- **Orphaned Content**: Content exists in DB but element removed from HTML
|
||||
- *Solution*: CLI warns + provides cleanup commands
|
||||
- *Example*: `⚠️ Content 'hero-title-abc123' no longer found (last seen: 2024-09-01)`
|
||||
|
||||
- **Content Drift**: Element text changes, breaking content-dependent IDs
|
||||
- *Solution*: IDs based on structure, not content text
|
||||
- *Example*: `<h1>Welcome</h1>` → `<h1>About Us</h1>` keeps same ID
|
||||
|
||||
- **Duplicate Resolution**: Multiple elements generate same ID pattern
|
||||
- *Solution*: Collision detection with incremental suffixes
|
||||
- *Example*: `hero-h1-abc123`, `hero-h1-def456`
|
||||
|
||||
**2. Structural Changes**
|
||||
- **Element Movement**: Same content, different DOM position
|
||||
- *Solution*: HTML `id` attributes provide stability anchors
|
||||
- *Example*: Moving `<h1>` between sections preserves ID if parent has `id`
|
||||
|
||||
- **Container Refactoring**: Switching between container vs individual `insertr` classes
|
||||
- *Solution*: Parser detects structural changes and suggests migrations
|
||||
- *Example*: `div.insertr` → individual child elements get mapped IDs
|
||||
|
||||
- **Framework Migrations**: Moving between SSGs changes HTML structure
|
||||
- *Solution*: HTML `id` attributes survive framework changes
|
||||
- *Content mapping*: Based on semantic meaning, not framework output
|
||||
|
||||
**3. Development Workflow Issues**
|
||||
- **Branch Conflicts**: Multiple developers changing same elements
|
||||
- *Solution*: Content stored separately from markup, no merge conflicts
|
||||
- *Database approach*: Conflicts resolved at content level, not Git level
|
||||
|
||||
- **Content Staging**: Handling content across dev/staging/prod environments
|
||||
- *Solution*: Environment-aware content API with fallbacks
|
||||
- *Workflow*: Dev content → Staging approval → Production deployment
|
||||
|
||||
- **Reset Scenarios**: Starting fresh vs preserving existing content
|
||||
- *Solution*: CLI provides reset/preserve options
|
||||
- *Commands*: `insertr reset --preserve-content` vs `insertr reset --clean`
|
||||
|
||||
#### Migration and Maintenance Tools
|
||||
|
||||
**Content Mapping Detection**:
|
||||
```bash
|
||||
# Detect moved/renamed content with confidence scoring
|
||||
insertr detect-changes --previous content-registry.json
|
||||
|
||||
⚠️ Potential content migrations detected:
|
||||
hero-old-title → hero-main-title (95% confidence)
|
||||
services-desc → about-story (12% confidence - manual review needed)
|
||||
|
||||
# Accept suggested migrations
|
||||
insertr migrate hero-old-title hero-main-title
|
||||
|
||||
# Cleanup orphaned content
|
||||
insertr cleanup --older-than 30d --confirm
|
||||
```
|
||||
|
||||
**Developer Override System**:
|
||||
```html
|
||||
<!-- Explicit control when needed -->
|
||||
<section id="hero">
|
||||
<h1 class="insertr">Title</h1> <!-- Stable: hero-h1-* -->
|
||||
<p class="insertr">Description</p> <!-- Stable: hero-p-* -->
|
||||
</section>
|
||||
|
||||
<!-- Complex case: manual ID override -->
|
||||
<h1 class="insertr" data-content-id="custom-stable-id">Special Case</h1>
|
||||
```
|
||||
|
||||
#### Benefits of This Approach
|
||||
|
||||
**For Development:**
|
||||
- Zero cognitive overhead for simple cases
|
||||
- HTML `id` attributes provide escape hatch for complex scenarios
|
||||
- Generated IDs invisible to developers in built output
|
||||
- Fast iteration without content persistence concerns
|
||||
|
||||
**For Production:**
|
||||
- Stable content mappings preserve editorial work
|
||||
- Graceful handling of structural changes
|
||||
- Clear migration paths for major refactoring
|
||||
- Content lifecycle tracking prevents data loss
|
||||
|
||||
**For Content Editors:**
|
||||
- Seamless editing experience regardless of ID complexity
|
||||
- Content preserved across site restructures
|
||||
- No exposure to technical ID management
|
||||
|
||||
This approach maintains the "zero configuration" philosophy while providing pragmatic solutions for production stability and content preservation.
|
||||
|
||||
---
|
||||
|
||||
## Strategic Recommendations
|
||||
|
||||
### 1. Market Positioning: "The Tailwind of CMS"
|
||||
|
||||
**Target Personas**:
|
||||
- Full-stack developers building client sites
|
||||
- Frontend developers adding editing to existing sites
|
||||
- Agencies needing client-friendly editing solutions
|
||||
- Budget-conscious teams avoiding enterprise CMS costs
|
||||
|
||||
**Core Message**: "Zero configuration content editing for any static site"
|
||||
|
||||
### 2. Technical Architecture: HTML Enhancement Service
|
||||
|
||||
**Core Components**:
|
||||
|
||||
1. **Enhancement CLI**:
|
||||
- Parse HTML and identify editable elements
|
||||
- Fetch latest content from database
|
||||
- Inject content and editing capabilities
|
||||
- Generate optimized bundles
|
||||
|
||||
2. **Content Storage API**:
|
||||
- Simple REST API for content CRUD
|
||||
- Database-backed (PostgreSQL/SQLite)
|
||||
- Multi-site content isolation
|
||||
- Authentication integration
|
||||
|
||||
3. **Smart Loading System**:
|
||||
- Conditional editor asset loading
|
||||
- Zero overhead for regular visitors
|
||||
- Rich editing experience for authenticated users
|
||||
|
||||
### 3. Differentiation Strategy
|
||||
|
||||
#### Against CloudCannon:
|
||||
- **Simplicity**: `class="insertr"` vs complex component schemas
|
||||
- **Setup Time**: 5 minutes vs days of configuration
|
||||
- **Pricing**: Developer-friendly vs enterprise focus
|
||||
- **Flexibility**: Works with any design vs rigid components
|
||||
|
||||
#### Against TinaCMS:
|
||||
- **Framework Agnostic**: Any SSG vs React/Next.js focus
|
||||
- **Zero Config**: Auto-generated IDs vs schema requirements
|
||||
- **Lightweight**: Focused enhancement vs full platform
|
||||
|
||||
#### Against Decap CMS:
|
||||
- **Better UX**: Rich in-place editing vs basic forms
|
||||
- **Smart Rebuilds**: Batched updates vs every commit
|
||||
- **Active Development**: Modern architecture vs maintenance mode
|
||||
|
||||
### 4. Implementation Roadmap
|
||||
|
||||
#### Phase 3a: Enhancement Engine (4-6 weeks)
|
||||
- CLI tool for HTML parsing and content injection
|
||||
- Auto-generated content ID system
|
||||
- Database-backed content storage API
|
||||
- Smart asset loading implementation
|
||||
|
||||
#### Phase 3b: Integration Examples (2-3 weeks)
|
||||
- GitHub Actions integration
|
||||
- Hugo/Jekyll/Next.js examples
|
||||
- Netlify/Vercel deployment guides
|
||||
- Performance optimization documentation
|
||||
|
||||
#### Phase 3c: Developer Experience (3-4 weeks)
|
||||
- Comprehensive documentation
|
||||
- Interactive setup guides
|
||||
- Video tutorials and examples
|
||||
- Community building initiatives
|
||||
|
||||
### 5. Success Metrics
|
||||
|
||||
**Developer Adoption**:
|
||||
- Setup time: **< 5 minutes** (vs hours/days for competitors)
|
||||
- Performance impact: **0% for visitors** (pure static delivery)
|
||||
- Integration complexity: **Single CLI command**
|
||||
|
||||
**User Experience**:
|
||||
- Edit-to-live time: **2-5 minutes** (build-dependent but acceptable)
|
||||
- Learning curve: **< 5 minutes** for content editors
|
||||
- Editor loading time: **< 2 seconds** for authenticated users
|
||||
|
||||
### 6. Go-to-Market Strategy
|
||||
|
||||
#### Developer-First Approach:
|
||||
1. **Open Source Core**: Build community credibility
|
||||
2. **Exceptional Documentation**: Focus on developer experience
|
||||
3. **Framework Integrations**: Support popular SSGs out of the box
|
||||
4. **Community Building**: Developer advocates, tutorials, examples
|
||||
|
||||
#### Pricing Strategy:
|
||||
```
|
||||
Free Tier: Open source, self-hosted, unlimited sites
|
||||
Hosted Tier: $9/month, hosted API, basic features
|
||||
Pro Tier: $29/month, advanced features, priority support
|
||||
Agency Tier: $99/month, multi-site management, white-label
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Conclusion
|
||||
|
||||
The strategic pivot to an "HTML Enhancement" approach positions Insertr uniquely in the CMS market. By embracing the "Tailwind philosophy" of utility-first, build-time optimization, and zero configuration, we can capture the under-served segment of developers who want powerful editing capabilities without architectural complexity.
|
||||
|
||||
Key advantages of this approach:
|
||||
|
||||
1. **Simplicity**: Eliminates file mapping and Git workflow complexity
|
||||
2. **Performance**: Zero runtime overhead for visitors, static site benefits maintained
|
||||
3. **Flexibility**: Works with any static site generator or HTML output
|
||||
4. **Developer Experience**: 5-minute setup vs days of traditional CMS configuration
|
||||
5. **Market Differentiation**: Unique positioning against component-heavy competitors
|
||||
|
||||
The modular architecture developed in earlier phases provides the perfect foundation for this enhancement-service approach. By focusing on being the best possible editing experience that works with any content system, rather than trying to solve the entire CMS workflow, Insertr can achieve sustainable growth in the developer tools market.
|
||||
|
||||
This "editing as a service" model represents the future of content management for static sites - lightweight, performant, and developer-friendly.
|
||||
@@ -105,6 +105,7 @@
|
||||
</footer>
|
||||
|
||||
<!-- Insertr JavaScript Library -->
|
||||
<script type="text/javascript" src="insertr.js"></script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -80,6 +80,8 @@
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<!-- Insertr JavaScript Library -->
|
||||
<script type="text/javascript" src="insertr.js"></script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -80,6 +80,12 @@ func runServedev(cmd *cobra.Command, args []string) {
|
||||
serveEditorAsset(w, r, assetPath)
|
||||
})
|
||||
|
||||
// Handle insertr library files
|
||||
http.HandleFunc("/insertr/", func(w http.ResponseWriter, r *http.Request) {
|
||||
assetPath := strings.TrimPrefix(r.URL.Path, "/insertr/")
|
||||
serveLibraryAsset(w, r, assetPath)
|
||||
})
|
||||
|
||||
// Handle all other requests with our enhanced file server
|
||||
http.Handle("/", fileServer)
|
||||
|
||||
@@ -120,6 +126,24 @@ func serveEditorAsset(w http.ResponseWriter, r *http.Request, assetPath string)
|
||||
http.ServeFile(w, r, assetFile)
|
||||
}
|
||||
|
||||
// serveLibraryAsset serves the insertr library files from embedded assets
|
||||
func serveLibraryAsset(w http.ResponseWriter, r *http.Request, assetPath string) {
|
||||
w.Header().Set("Content-Type", "application/javascript")
|
||||
|
||||
var script string
|
||||
switch assetPath {
|
||||
case "insertr.js":
|
||||
script = content.GetLibraryScript(false)
|
||||
case "insertr.min.js":
|
||||
script = content.GetLibraryScript(true)
|
||||
default:
|
||||
http.NotFound(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
w.Write([]byte(script))
|
||||
}
|
||||
|
||||
// enhancedFileSystem wraps http.FileSystem to provide enhanced HTML serving
|
||||
type enhancedFileSystem struct {
|
||||
fs http.FileSystem
|
||||
|
||||
@@ -133,34 +133,19 @@ func (i *Injector) addContentAttributes(node *html.Node, contentID string, conte
|
||||
i.addClass(node, "insertr")
|
||||
}
|
||||
|
||||
// InjectEditorAssets adds editor JavaScript and CSS to HTML document
|
||||
// InjectEditorAssets adds editor JavaScript to HTML document
|
||||
func (i *Injector) InjectEditorAssets(doc *html.Node, isDevelopment bool, libraryScript string) {
|
||||
if !isDevelopment {
|
||||
return // Only inject in development mode for now
|
||||
}
|
||||
// TODO: Implement script injection strategy when we have CDN hosting
|
||||
// For now, script injection is disabled since HTML files should include their own script tags
|
||||
// Future options:
|
||||
// 1. Inject CDN script tag: <script src="https://cdn.jsdelivr.net/npm/@insertr/lib@1.0.0/dist/insertr.js"></script>
|
||||
// 2. Inject local script tag for development: <script src="/insertr/insertr.js"></script>
|
||||
// 3. Continue with inline injection for certain use cases
|
||||
|
||||
// Find the head element
|
||||
head := i.findHeadElement(doc)
|
||||
if head == nil {
|
||||
// Currently disabled to avoid duplicate scripts
|
||||
return
|
||||
}
|
||||
|
||||
// Add inline script with embedded library
|
||||
// Note: Using html.TextNode for scripts can cause issues with HTML entity encoding
|
||||
// Instead, we'll insert the script tag as raw HTML
|
||||
scriptHTML := fmt.Sprintf(`<script type="text/javascript">
|
||||
%s
|
||||
</script>`, libraryScript)
|
||||
|
||||
// Parse the script HTML and append to head
|
||||
scriptNodes, err := html.ParseFragment(strings.NewReader(scriptHTML), head)
|
||||
if err == nil && len(scriptNodes) > 0 {
|
||||
for _, node := range scriptNodes {
|
||||
head.AppendChild(node)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// findHeadElement finds the <head> element in the document
|
||||
func (i *Injector) findHeadElement(node *html.Node) *html.Node {
|
||||
if node.Type == html.ElementNode && node.Data == "head" {
|
||||
|
||||
@@ -2,6 +2,7 @@ package content
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// Embedded library assets
|
||||
@@ -24,3 +25,26 @@ func GetLibraryScript(minified bool) string {
|
||||
func GetLibraryVersion() string {
|
||||
return "1.0.0"
|
||||
}
|
||||
|
||||
// GetLibraryURL returns the appropriate library URL for script injection
|
||||
func GetLibraryURL(minified bool, isDevelopment bool) string {
|
||||
if isDevelopment {
|
||||
// Local development URLs - relative to served content
|
||||
if minified {
|
||||
return "/insertr/insertr.min.js"
|
||||
}
|
||||
return "/insertr/insertr.js"
|
||||
}
|
||||
|
||||
// Production URLs - use CDN
|
||||
return GetLibraryCDNURL(minified)
|
||||
}
|
||||
|
||||
// GetLibraryCDNURL returns the CDN URL for production use
|
||||
func GetLibraryCDNURL(minified bool) string {
|
||||
version := GetLibraryVersion()
|
||||
if minified {
|
||||
return fmt.Sprintf("https://cdn.jsdelivr.net/npm/@insertr/lib@%s/dist/insertr.min.js", version)
|
||||
}
|
||||
return fmt.Sprintf("https://cdn.jsdelivr.net/npm/@insertr/lib@%s/dist/insertr.js", version)
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ set -e
|
||||
|
||||
echo "🔄 Library changed, rebuilding..."
|
||||
|
||||
# Build the library
|
||||
# Build the library (this will also copy to demo-site)
|
||||
cd ../lib
|
||||
npm run build --silent
|
||||
|
||||
|
||||
@@ -10,7 +10,9 @@
|
||||
"src/"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "rollup -c",
|
||||
"build": "rollup -c && npm run copy:demo",
|
||||
"build:only": "rollup -c",
|
||||
"copy:demo": "cp dist/insertr.js ../demo-site/insertr.js",
|
||||
"watch": "rollup -c -w",
|
||||
"dev": "rollup -c -w",
|
||||
"serve": "node scripts/dev.js serve",
|
||||
|
||||
Reference in New Issue
Block a user