2.2 KiB
2.2 KiB
Landing Page (Public Page Renderer)
Overview
File Path: admin/src/pages/public/LandingPage.tsx (68 lines)
Route: /p/:slug
Role Requirements: Public access
Purpose: Simple renderer for admin-authored landing pages created with GrapesJS editor. Fetches page by slug and displays HTML/CSS content with SEO meta tags.
Key Features:
- Minimal wrapper around admin-authored HTML
- SEO meta tags (title, description, og:image)
- dangerouslySetInnerHTML for HTML + CSS rendering
- Loading spinner during fetch
- 404 page for invalid slugs
- No layout wrapper (pages are self-contained)
Features
1. SEO Meta Tags
<Helmet>
<title>{page.title}</title>
<meta name="description" content={page.description || ''} />
<meta property="og:title" content={page.title} />
<meta property="og:description" content={page.description || ''} />
{page.coverImage && <meta property="og:image" content={page.coverImage} />}
</Helmet>
2. HTML Rendering
<div dangerouslySetInnerHTML={{ __html: page.html }} />
<style>{page.css}</style>
3. Loading State
{loading && (
<div style={{ textAlign: 'center', padding: 100 }}>
<Spin size="large" />
</div>
)}
4. 404 Handling
{!loading && !page && (
<Result
status="404"
title="Page Not Found"
subTitle="The page you're looking for doesn't exist."
extra={<Link to="/"><Button type="primary">Go Home</Button></Link>}
/>
)}
API Integration
GET /api/public/pages/:slug
Response:
{
"slug": "welcome",
"title": "Welcome to Our Campaign",
"description": "Join us in making a difference",
"html": "<div><h1>Welcome</h1>...</div>",
"css": "h1 { color: #1890ff; }",
"coverImage": "https://example.com/cover.jpg",
"isPublished": true
}
Security Considerations
XSS Risk Accepted:
- Pages authored by trusted admins only
- dangerouslySetInnerHTML allows full HTML/JS
- No user-submitted content
- Alternative would break GrapesJS output