X Tutup
Skip to content

feat: live previews [WIP]#336

Open
regalstreak wants to merge 2 commits intopages-cms:mainfrom
regalstreak:previews
Open

feat: live previews [WIP]#336
regalstreak wants to merge 2 commits intopages-cms:mainfrom
regalstreak:previews

Conversation

@regalstreak
Copy link

@regalstreak regalstreak commented Dec 4, 2025

Adds Real-Time Preview Panel

Screen.Recording.2025-12-05.at.4.08.41.AM.mov

Overview

This PR introduces a real-time preview panel that displays live content updates as users edit collection files. The preview shows the actual rendered website with content changes reflected instantly, providing a WYSIWYG editing experience.

Features

✨ Real-Time Preview

  • Live Updates: Preview updates automatically as you type (debounced to 300ms)
  • No Reloads: Content updates happen via direct DOM manipulation, eliminating flashing/reloading
  • Scroll Preservation: Scroll position is maintained during content updates
  • Client-Side Processing: Markdown rendering and DOM updates happen in the browser for instant feedback

🎯 Framework Support

  • Astro Support (MVP): Currently supports Astro sites with full markdown rendering pipeline
  • Framework Detection: Automatically detects Astro projects via package.json and config files
  • Extensible: Architecture supports adding more frameworks in the future

⚡ Performance Optimizations

  • Base HTML Caching: Base HTML is fetched once per file, not on every keystroke
  • Client-Side Rendering: Markdown-to-HTML conversion happens in the browser using remark/rehype
  • Direct DOM Updates: Content is injected directly into iframe DOM without reloading
  • Reduced API Calls: Only one API call to fetch base HTML, then all updates are client-side

Technical Implementation

New API Endpoints

GET /api/[owner]/[repo]/[branch]/preview/base

Fetches the base HTML for a preview page. Called once when opening a file or switching files.

Query Parameters:

  • filePath: Path to the file being edited
  • name: Schema/collection name

Returns:

{
  "status": "success",
  "data": {
    "html": "<html>...</html>",
    "pageUrl": "https://example.com/page",
    "contentSelector": "main"
  }
}

POST /api/[owner]/[repo]/[branch]/preview (Legacy)

Original endpoint that returns fully processed HTML. Kept for backward compatibility but not used by the new client-side implementation.

New Components

EntryPreview

React component that:

  • Fetches base HTML once when file path changes
  • Renders markdown client-side using remark/rehype pipeline
  • Updates iframe DOM directly without reloading
  • Preserves scroll position during updates

Configuration Schema

Preview configuration is added to collection schemas in .pages.yml:

content:
  - name: articles
    preview:
      url: https://your-site.com
      enabled: true
      selector: main  # CSS selector for content area (defaults to "main")

Configuration Options:

  • url (required): Base URL of the deployed site
  • enabled (optional): Enable/disable preview (defaults to true)
  • selector (optional): CSS selector for the content area (defaults to "main")

URL Mapping

File paths are automatically mapped to preview URLs:

  • src/content/articles/something/myarticle.mdhttps://site.com/something/myarticle
  • Uses schema.path as input and empty string as output for path transformation
  • Removes src/content/ or content/ prefixes
  • Removes file extensions

Markdown Rendering

Uses the same rendering pipeline as Astro:

  • remark-gfm: GitHub Flavored Markdown support
  • remark-rehype: Converts markdown AST to HTML AST
  • rehype-sanitize: Sanitizes HTML for security
  • rehype-stringify: Converts HTML AST to string

Supports:

  • Rich-text fields (detects markdown vs HTML)
  • Code fields with markdown format
  • Text fields

User Experience

Preview Panel

  • Toggle button in the entry editor to show/hide preview
  • Side-by-side or stacked layout (responsive)
  • Loading states and error messages
  • Smooth, non-flashing updates

Content Detection

  • Automatically finds the "body" field or first markdown/rich-text field
  • Detects if rich-text content is markdown or HTML
  • Handles list-wrapped content structures

Error Handling

  • Clear error messages for missing configuration
  • Network error handling with helpful messages
  • Timeout handling (10 seconds)
  • Fallback selectors if primary selector not found

Dependencies Added

  • cheerio: Server-side HTML parsing (for legacy endpoint)
  • remark: Markdown processing
  • remark-gfm: GitHub Flavored Markdown
  • remark-rehype: Markdown to HTML conversion
  • rehype-sanitize: HTML sanitization
  • rehype-stringify: HTML stringification

Files Changed

New Files

  • app/api/[owner]/[repo]/[branch]/preview/base/route.ts - Base HTML endpoint
  • components/entry/entry-preview.tsx - Preview component
  • lib/utils/framework-detector.ts - Framework detection utility

Modified Files

  • lib/configSchema.ts - Added preview configuration schema
  • lib/config.ts - Added preview config normalization
  • lib/schema.ts - Added mapFilePathToPreviewUrl function
  • components/entry/entry-form.tsx - Integrated preview component
  • package.json - Added new dependencies

Testing

Manual Testing Checklist

  • Preview panel shows/hides correctly
  • Base HTML loads when opening a file
  • Content updates as you type (no flashing)
  • Scroll position is preserved
  • Markdown renders correctly
  • Rich-text fields work (both markdown and HTML)
  • URL mapping works correctly
  • Error messages display properly
  • Preview works with different content selectors

Future Enhancements

  • Support for other static site generators (Next.js, Nuxt, etc.)
  • Preview for multiple fields simultaneously
  • Preview for media/image fields
  • Preview caching/optimization
  • Preview for draft/unpublished content
  • Custom preview transformations

Breaking Changes

None. This is a new feature that doesn't affect existing functionality.

Migration Guide

To enable preview for a collection, add the preview configuration to your .pages.yml:

content:
  - name: your-collection
    preview:
      url: https://your-deployed-site.com
      selector: main  # Optional, defaults to "main"

The preview panel will automatically appear in the entry editor when preview is configured.

@regalstreak regalstreak changed the title feat: previews for astro [WIP] feat: live previews [WIP] Dec 4, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

X Tutup