341 lines
7.4 KiB
Markdown

# Landing Pages (Page Builder)
The Landing Pages feature provides a complete page building system with WYSIWYG editing, custom blocks, MkDocs export, and public rendering. Build custom landing pages without code.
## Overview
The Landing Pages system consists of four integrated components:
1. **[Page Builder](../pages/page-builder.md)** - Page CRUD and management
2. **[GrapesJS Editor](../pages/grapes-editor.md)** - WYSIWYG editor
3. **[Block Library](../pages/block-library.md)** - Reusable content blocks
4. **[MkDocs Export](../pages/mkdocs-export.md)** - Export to Jinja2 templates
## Features
### WYSIWYG Editor
- GrapesJS integration
- Drag-and-drop interface
- Visual editing
- Component customization
- CSS styling
- Responsive preview
- Desktop-only (mobile warning)
### Block Library
Pre-built components:
- **Hero sections** - Large header with CTA
- **Feature grids** - Multi-column features
- **Call-to-action** - Button sections
- **Text blocks** - Rich text content
- **Image galleries** - Photo grids
- **Forms** - Contact forms (future)
- **Custom HTML** - Raw HTML blocks
### Page Management
- Create/edit/delete pages
- Slug management (URL-friendly)
- Meta tags (title, description)
- Published/draft status
- Page settings (layout, scripts)
- Search and filtering
### MkDocs Export
- Export to Jinja2 Material theme templates
- Custom overrides directory
- Static page generation
- SEO optimization
- Template inheritance
## User Flow
### Admin Experience
1. **Create Page** (`/app/pages`)
- Click "New Page"
- Enter title and slug
- Set meta description
- Save draft
2. **Edit Page** (`/app/pages/:id/edit`)
- Full-screen GrapesJS editor
- Drag blocks from sidebar
- Customize components
- Ctrl+S to save
- Preview changes
3. **Publish Page**
- Set status to "Published"
- Page appears at `/p/:slug`
- Listed in page table
4. **Export to MkDocs** (`/app/services/docs`)
- Select pages to export
- Click "Export"
- Pages saved to MkDocs overrides
- Rebuild MkDocs site
### Public Experience
1. **View Landing Page** (`/p/:slug`)
- Rendered HTML/CSS
- Custom styling
- Responsive design
- SEO metadata
## Architecture
### Backend Components
**Module:**
- `api/src/modules/pages/pages-admin.routes.ts` - Admin CRUD
- `api/src/modules/pages/pages-public.routes.ts` - Public renderer
- `api/src/modules/pages/blocks.routes.ts` - Block library API
- `api/src/modules/pages/pages.service.ts` - Business logic
- `api/src/modules/pages/pages.schemas.ts` - Zod validation
**Database Models:**
- `Page` - Page definitions (title, slug, html, css, settings)
- `PageBlock` - Reusable block library
### Frontend Components
**Admin Pages:**
- `admin/src/pages/LandingPagesPage.tsx` - Page management table
- `admin/src/pages/PageEditorPage.tsx` - Full-screen editor
**Public Pages:**
- `admin/src/pages/public/LandingPage.tsx` - Page renderer
**Editor Component:**
- `admin/src/components/GrapesJSEditor.tsx` - GrapesJS wrapper
## Configuration
### Environment Variables
```bash
# MkDocs export directory (inside Docker)
MKDOCS_EXPORT_DIR=/mkdocs/docs/overrides
```
### Page Settings
Each page can configure:
- **Meta title** - Browser title tag
- **Meta description** - SEO description
- **Custom CSS** - Page-specific styles
- **Custom JS** - Page-specific scripts
- **Layout** - Template wrapper (future)
## GrapesJS Integration
### Editor Setup
```typescript
import grapesjs from 'grapesjs';
const editor = grapesjs.init({
container: '#gjs',
fromElement: true,
height: '100vh',
storageManager: false, // Save via API
canvas: {
styles: [...], // Custom styles
scripts: [...], // Custom scripts
},
blockManager: {
blocks: customBlocks, // Block library
},
});
```
### Custom Blocks
Blocks defined in `GrapesJSEditor.tsx`:
```typescript
const customBlocks = [
{
id: 'hero-section',
label: 'Hero Section',
content: '<div class="hero">...</div>',
category: 'Basic',
},
{
id: 'feature-grid',
label: 'Feature Grid',
content: '<div class="features">...</div>',
category: 'Content',
},
// ... more blocks
];
```
### Save Handler
Ctrl+S keyboard shortcut:
```typescript
editor.on('run:core:save', () => {
const html = editor.getHtml();
const css = editor.getCss();
onSave({ html, css });
});
```
## MkDocs Export
### Export Process
1. **Select Pages** - Admin selects pages to export
2. **Generate Jinja2** - Wrap HTML in Material theme template
3. **Save to Overrides** - Write to `mkdocs/docs/overrides/`
4. **Configure Front Matter** - Set template, title, description
5. **Rebuild Site** - MkDocs regenerates static site
### Jinja2 Template Wrapper
```jinja2
{% extends "main.html" %}
{% block content %}
<style>
{{ page_css }}
</style>
{{ page_html }}
{% endblock %}
```
### Front Matter
```yaml
---
template: custom-page.html
title: Page Title
description: Page description for SEO
---
```
## Database Schema
### Page Model
```prisma
model Page {
id Int @id @default(autoincrement())
title String
slug String @unique
html String @db.Text
css String? @db.Text
settings Json?
published Boolean @default(false)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
```
### PageBlock Model
```prisma
model PageBlock {
id Int @id @default(autoincrement())
name String
category String
html String @db.Text
css String? @db.Text
thumbnail String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
```
## API Endpoints
### Admin Endpoints
```
GET /api/pages # List pages
POST /api/pages # Create page
GET /api/pages/:id # Get page
PATCH /api/pages/:id # Update page
DELETE /api/pages/:id # Delete page
POST /api/pages/export-mkdocs # Export to MkDocs
GET /api/pages/blocks # Get block library
POST /api/pages/blocks # Create block
```
### Public Endpoints
```
GET /api/pages/public/:slug # Get published page by slug
```
## Desktop-Only Editor
GrapesJS editor requires desktop browser:
```typescript
const screens = Grid.useBreakpoint();
const isMobile = !screens.md;
if (isMobile) {
return (
<Alert
message="Desktop Required"
description="Page editor requires desktop browser"
type="warning"
/>
);
}
```
## Best Practices
### Slug Management
- Auto-generate from title
- URL-friendly (lowercase, hyphens)
- Unique constraint
- Update URL on slug change
### SEO Optimization
- Meta title (50-60 chars)
- Meta description (150-160 chars)
- Semantic HTML structure
- Alt text for images
- Heading hierarchy
### Performance
- Minify CSS
- Lazy load images
- Async scripts
- Cache rendered pages
### Responsive Design
- Mobile-first CSS
- Flexible grids
- Responsive images
- Touch-friendly buttons
## Related Documentation
- [Page Builder](../pages/page-builder.md)
- [GrapesJS Editor](../pages/grapes-editor.md)
- [Block Library](../pages/block-library.md)
- [MkDocs Export](../pages/mkdocs-export.md)
- [Backend Pages Module](../../backend/modules/pages.md)
- [Landing Pages Page](../../frontend/pages/admin/landing-pages-page.md)
- [Page Editor Page](../../frontend/pages/admin/page-editor-page.md)
- [Content Editor Guide](../../user-guides/content-editor-guide.md)