# Site Builder - Project Documentation ## Overview A visual drag-and-drop website builder using GrapesJS. Users can create multi-page websites without writing code, with server-side file storage for assets and localStorage persistence for editor state. ## File Structure ``` site-builder/ ├── router.php # PHP built-in server router (dev server) ├── .htaccess # Apache rewrite rules for /api/* routing ├── .user.ini # PHP upload/memory limits for Apache ├── index.html # Main editor page ├── preview.html # Preview page (renders saved content with page navigation) ├── CLAUDE.md # This documentation file ├── api/ │ ├── index.php # API handler (assets, projects, health endpoints) │ └── image-resize.php # Image resize/crop endpoint ├── css/ │ └── editor.css # Custom editor styles (dark theme, ~1300 lines) ├── js/ │ ├── editor.js # Editor initialization and all functionality (~1900 lines) │ ├── assets.js # Asset management (upload, browse, deploy) │ └── whp-integration.js # WHP control panel integration ├── storage/ │ ├── assets/ # Uploaded asset files (images, videos, etc.) │ ├── projects/ # Saved project data (JSON files) │ └── tmp/ # Temporary files └── docs/ └── plans/ └── 2026-01-26-site-builder-design.md # Design document ``` ## Dependencies (CDN) All dependencies are loaded from CDN in index.html: - **GrapesJS Core** (`unpkg.com/grapesjs`) - Main editor engine - **grapesjs-blocks-basic** - Basic building blocks - **grapesjs-preset-webpage** - Webpage blocks (hero, features, etc.) - **grapesjs-plugin-forms** - Form elements - **grapesjs-style-gradient** - Gradient background support - **Font Awesome 5** - Block icons - **Google Fonts** - Inter, Roboto, Open Sans, Poppins, Montserrat, Playfair Display, Merriweather, Source Code Pro ## Running the Project The project uses PHP for its API backend. Assets are stored as files on disk (not base64 in localStorage), which avoids browser storage quota issues. ### Production (Apache) The `.htaccess` file routes `/api/*` requests to `api/index.php`. The `.user.ini` sets PHP upload limits. Just deploy to any Apache + PHP host. ### Local Development (PHP built-in server) ```bash php -d upload_max_filesize=500M -d post_max_size=512M -S localhost:8081 router.php ``` Then open `http://localhost:8081` ### Server API Endpoints | Method | Endpoint | Description | |--------|----------|-------------| | GET | `/api/health` | Server health check | | POST | `/api/assets/upload` | Upload file (multipart/form-data) | | GET | `/api/assets` | List all stored assets | | DELETE | `/api/assets/` | Delete an asset | | POST | `/api/projects/save` | Save project data (JSON body) | | GET | `/api/projects/list` | List all saved projects | | GET | `/api/projects/` | Load a specific project | | DELETE | `/api/projects/` | Delete a project | ## Editor Interface ### Top Navigation Bar - Logo/branding - Device switcher (Desktop/Tablet/Mobile) - Undo/Redo buttons - Clear canvas button - Export button (download site as ZIP with options) - Preview button (opens preview.html in new tab) ### Left Panel (3 tabs) 1. **Blocks** - Draggable components organized by category 2. **Pages** - Multi-page management (add/edit/delete pages) 3. **Layers** - Component hierarchy tree view ### Center Canvas - Live preview of the website - Click to select, drag to reposition - Right-click for context menu - Resize handles on selected components ### Right Panel (2 tabs) 1. **Styles** - Two modes: - **Guided Mode**: Context-aware presets based on selected element type - **Advanced Mode**: Full GrapesJS style manager with all CSS properties 2. **Settings** - Component-specific traits/attributes (like Video URL) ## Block Categories ### Layout | Block | Description | |-------|-------------| | Section | Basic content section with centered container | | Section (Background) | Section with image background and overlay | | Section (Video BG) | Section with video background (YouTube/Vimeo/MP4) and overlay | | Logo | Styled logo with icon and text | | Navigation | Dynamic nav bar with page sync | | Footer | Footer with links and copyright | | 1-4 Columns | Flexible column layouts | | 2 Columns 3/7 | Asymmetric column layout | ### Basic | Block | Description | |-------|-------------| | Text | Paragraph text | | Heading | H2 heading | | Button | Styled link button | | Divider | Horizontal rule (color/thickness editable) | | Spacer | Vertical spacing element | | Text Box | Styled container for overlaying on backgrounds | ### Media | Block | Description | |-------|-------------| | Image | Responsive image | | Video | Universal video (YouTube, Vimeo, or direct file) | ### Sections | Block | Description | |-------|-------------| | Hero (Image) | Hero with image background and overlay | | Hero (Video) | Hero with video background and overlay | | Hero (Simple) | Hero with gradient background | | Features Grid | 3-column feature cards | | Testimonials | Customer testimonials with star ratings | | Pricing Table | 3-tier pricing comparison with featured tier | | Contact Section | Contact info with form | | Call to Action | CTA banner with gradient background | ### Forms Form, Input, Textarea, Select, Button, Label, Checkbox, Radio ## Context-Aware Styling (Guided Mode) The guided panel shows different controls based on selected element: ### Text Elements (p, h1-h6, span, label) - Text Color (8 presets) - Font Family (8 Google Fonts) - Text Size (XS, S, M, L, XL, 2XL) - Font Weight (Light, Normal, Medium, Semi, Bold) ### Links/Buttons (a) - Link URL input with "Open in new tab" option - Button Color (8 presets, auto-adjusts text for contrast) - Text styling options - Border Radius and Padding ### Containers (div, section, etc.) - Background Color (8 presets) - Background Gradient (12 presets) - Background Image (URL with size/position controls) - Padding and Border Radius ### Overlays (.bg-overlay) - Overlay Color (6 presets) - Opacity Slider (0-100%) ### Navigation (nav) - "Sync with Pages" button (auto-generates links from page list) - "Add Link" button - Link list with delete buttons ### Dividers (hr) - Divider Color (8 presets) - Line Thickness (1-6px) ## Video System ### Supported Formats The Video block and Section Video BG support: - **YouTube**: `youtube.com/watch?v=ID`, `youtu.be/ID` - **Vimeo**: `vimeo.com/ID` - **Direct files**: `.mp4`, `.webm`, `.ogg`, `.mov` ### How Videos Work 1. URLs are auto-detected and converted to proper embed format 2. YouTube/Vimeo use iframe embeds 3. Direct files use HTML5 video element 4. Background videos auto-play muted and loop ### Editing Video URL 1. Select the video container (use Layers panel if needed) 2. Go to **Settings** tab 3. Paste URL in "Video URL" field 4. Video loads automatically ## Multi-Page System ### Storage - Pages stored in localStorage key: `sitebuilder-pages` - Each page has: id, name, slug, html, css ### Page Management - **Add Page**: Click "Add Page" in Pages tab - **Edit Page**: Click edit icon on page item - **Delete Page**: Click delete icon (cannot delete last page) - **Switch Pages**: Click on page item (auto-saves current page) ### Navigation Sync 1. Add Navigation block to page 2. Select the nav element 3. In Settings, click "Sync with Pages" 4. Links auto-generate from page list 5. CTA button (with `.nav-cta` class) is preserved ## Context Menu (Right-Click) | Action | Shortcut | Description | |--------|----------|-------------| | Edit Content | - | Enable inline text editing | | Duplicate | Ctrl+D | Copy element in place | | Copy | Ctrl+C | Copy to clipboard | | Paste | Ctrl+V | Paste from clipboard | | Move Up | - | Move element up in parent | | Move Down | - | Move element down in parent | | Select Parent | - | Select parent container | | Wrap in Container | - | Wrap in new div | | Delete | Del | Remove element | ## Keyboard Shortcuts | Shortcut | Action | |----------|--------| | Ctrl/Cmd + Z | Undo | | Ctrl/Cmd + Shift + Z | Redo | | Ctrl/Cmd + Y | Redo (alternative) | | Ctrl/Cmd + C | Copy | | Ctrl/Cmd + V | Paste | | Ctrl/Cmd + D | Duplicate | | Delete / Backspace | Remove selected | | Escape | Deselect / Close modals | ## Storage Architecture ### Server-Side Storage (primary, when server.py is running) | Location | Purpose | |----------|---------| | `storage/assets/` | Uploaded files (images, videos, etc.) stored on disk | | `storage/projects/` | Project data as JSON files | | `storage/tmp/` | Temporary files | Assets are uploaded via `POST /api/assets/upload` and stored as actual files on disk. They are referenced in the editor by URL (e.g., `/storage/assets/1234567_abc123_photo.jpg`), avoiding localStorage quota limits. ### localStorage Keys (lightweight metadata and editor state) | Key | Purpose | |-----|---------| | `sitebuilder-project` | GrapesJS auto-save (components, styles) | | `sitebuilder-pages` | Multi-page data (array of page objects) | | `sitebuilder-assets` | Asset metadata index (URLs and names only, no file contents) | | `sitebuilder-project-preview` | Preview data (all pages for preview.html) | **Important:** Asset file contents (images, videos) are NOT stored in localStorage. Only metadata (filename, URL, type) is cached there. This prevents the `QuotaExceededError` that occurred with base64-encoded large files. ## Export Feature ### How to Export 1. Click the **Export** button in the top navigation bar 2. Choose export options: - **Minify CSS**: Reduces file size by removing whitespace/comments - **Include Google Fonts**: Adds font preload links (recommended) 3. Click **Download ZIP** 4. All pages are exported as standalone HTML files ### Exported File Structure ``` site-export.zip ├── index.html # Home page ├── about.html # About page (based on page slug) ├── contact.html # etc. ``` ### Technical Details - Uses JSZip library (loaded dynamically on first export) - Each HTML file includes embedded CSS styles - Responsive CSS reset included in each file - Mobile column stacking rules included ## Preview System `preview.html` loads saved content from localStorage and renders it: - Supports multi-page with page selector buttons - Backwards compatible with legacy single-page format - Includes Google Fonts and responsive styles - "Back to Editor" button ## CSS Architecture (editor.css) ### Main Sections 1. **Base Layout** (~lines 1-100) - Editor container, panels 2. **Top Navigation** (~lines 100-200) - Nav bar, device buttons 3. **Left Panel** (~lines 200-400) - Blocks, pages, layers 4. **Right Panel** (~lines 400-600) - Styles, traits 5. **Guided Styles** (~lines 600-800) - Color presets, font presets 6. **Context Menu** (~lines 800-900) - Right-click menu 7. **Pages Panel** (~lines 900-1000) - Page list, page items 8. **Modals** (~lines 1000-1100) - Page settings modal 9. **New Controls** (~lines 1100-1300) - Background, overlay, nav controls ### Theme - Dark theme with `#16161a` base - Accent color: `#3b82f6` (blue) - Text: `#e4e4e7` (light gray) - Borders: `#3f3f46` (dark gray) ## JavaScript Architecture (editor.js) ### Structure (approximate line numbers) 1. **GrapesJS Init** (1-200) - Editor configuration, plugins 2. **Custom Blocks** (200-820) - All block definitions including new sections 3. **Component Types** (900-1040) - Video wrapper types with traits 4. **Device Switching** (1040-1080) 5. **Undo/Redo/Clear** (1080-1120) 6. **Preview** (1120-1140) 7. **Panel Tabs** (1140-1200) 8. **Style Mode Toggle** (1200-1220) 9. **Context-Aware UI** (1220-1400) - Element type detection, section visibility 10. **Color/Style Presets** (1400-1600) - Click handlers for all presets 11. **Background/Overlay Controls** (1600-1700) 12. **Navigation Controls** (1700-1800) - Sync with pages, add/remove links 13. **Link Editing** (1800-1850) 14. **Save Status** (1850-1900) 15. **Keyboard Shortcuts** (1900-1950) 16. **Selection Handling** (1950-2050) - Update UI on selection change 17. **Context Menu** (2050-2200) - Right-click functionality 18. **Page Management** (2200-2600) - Pages CRUD, switching, modals 19. **Export Functionality** (2630-2810) - ZIP export with JSZip ### Key Functions - `convertToEmbedUrl(url)` - Converts YouTube/Vimeo URLs to embed format - `applyVideoUrl(component, url)` - Applies video to wrapper component - `getElementType(tagName)` - Returns element category for context-aware UI - `showSectionsForElement(component)` - Shows relevant guided panel sections - `loadPages()` / `savePages()` - Page persistence - `switchToPage(pageId)` - Page switching with auto-save - `loadNavLinks(component)` - Populate nav links list in guided panel - `generatePageHtml(page, includeFonts, minifyCss)` - Generate standalone HTML for export - `createAndDownloadZip(includeFonts, minifyCss)` - Create ZIP and trigger download ## Development Notes ### Adding New Blocks 1. Add to `blockManager.add()` section 2. Choose appropriate category 3. Use inline styles for immediate visibility 4. Add `data-*` attributes for custom component types if needed ### Adding New Guided Controls 1. Add HTML section in `index.html` inside `#guided-styles` 2. Add section reference in `sections` object 3. Update `showSectionsForElement()` to show for relevant element types 4. Add click handlers for presets 5. Add CSS in `editor.css` ### Custom Component Types Use `editor.DomComponents.addType()` for: - Custom traits in Settings panel - Special behavior on attribute changes - Detection via `isComponent` function ### Testing Video Embeds YouTube/Vimeo embeds may not work in GrapesJS canvas (nested iframe issue) but work correctly in Preview mode and published sites. ## Future Enhancements (from design doc) ### Phase 2: Backend Integration - PHP backend for user authentication - Database storage for projects - Multiple project support ### Phase 3: Publishing - Save/publish sites to server - Subdomain or custom domain support - Template library ### Phase 4: Enhancements - More block types - Custom CSS injection - Asset manager for images - SEO settings per page