Skip to content

ankurrokad/handlebar-parse

Repository files navigation

HBS Parser - Real-time Handlebars Template Editor

A modern, production-ready web application for real-time Handlebars template development with live preview, built with Next.js, Monaco Editor, and a beautiful dark theme UI.

πŸš€ Features

Core Functionality

  • Real-time Handlebars Compilation - Instant template rendering as you type
  • Live HTML Preview - See results immediately in a responsive preview panel
  • Layout System - Support for Handlebars layouts with {{{body}}} placeholder
  • Custom CSS Styling - Dedicated styles tab for template customization
  • Auto-save - Automatic Supabase persistence for all content
  • Manual Save - Ctrl+S shortcut for immediate saving

Editor Features

  • Monaco Editor Integration - VS Code-like editing experience
  • Syntax Highlighting - Support for Handlebars, HTML, CSS, and JSON
  • Auto-completion - Intelligent suggestions for all supported languages
  • Multiple Tabs - Organized workflow: Layout β†’ Body β†’ Data β†’ Styles
  • Import/Export - File upload support for all content types
  • Copy Functionality - Copy current tab content or final HTML

Developer Experience

  • Dark Theme - Professional dark UI with Vercel-inspired colors
  • Responsive Design - Full-screen layout optimized for development
  • Keyboard Shortcuts - Ctrl+S for save, intuitive navigation
  • Error Handling - Clear error messages with syntax highlighting
  • Auto-play Toggle - Control real-time compilation
  • Layout Toggle - Enable/disable layout system

Advanced Features

  • Custom Handlebars Helpers - Built-in helpers for common operations
  • Persistent Storage - All work automatically saved to Supabase
  • Reset to Defaults - Quick restoration of sample templates
  • Theme Persistence - User preferences saved across sessions
  • Responsive Preview - Mobile-friendly HTML rendering

πŸ—οΈ Architecture & Code Quality

Modern React Architecture

The application follows modern React best practices with a clean, maintainable architecture:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚   Monaco Editor β”‚    β”‚  Handlebars.js  β”‚    β”‚  Live Preview   β”‚
β”‚   (Input)       │───▢│  (Compiler)     │───▢│  (Output)       β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Component Structure

The codebase is organized into focused, reusable components:

components/
β”œβ”€β”€ layout/          # Header, Background, MainContent
β”œβ”€β”€ editor/          # LeftPanel, TabNavigation, EditorPanel, MonacoEditor
└── preview/         # RightPanel, PreviewPanel

lib/
β”œβ”€β”€ hooks/           # useEditor, useTheme
└── utils/           # File operations, clipboard functions

Key Benefits

βœ… Maintainable: Each component has a single responsibility
βœ… Reusable: Components can be shared across the application
βœ… Testable: Individual pieces can be tested in isolation
βœ… Performance: Better code splitting and optimization
βœ… Developer Experience: Easy to navigate and debug

Data Flow & State Management

  1. User Input β†’ Monaco Editor captures changes in real-time
  2. State Update β†’ Custom hooks manage state updates and trigger re-renders
  3. Handlebars Compilation β†’ Template + Data + Layout compiled together
  4. CSS Injection β†’ Custom styles automatically injected into output
  5. HTML Rendering β†’ Final HTML displayed in preview panel
  6. Auto-save β†’ All content automatically persisted to Supabase

State Management Architecture

  • useEditor Hook: Centralizes all editor state and Handlebars compilation logic
  • useTheme Hook: Manages theme state and storage persistence
  • useStorage Hook: Manages storage provider switching and configuration
  • Component Props: Clean data flow with props down, events up pattern
  • Separation of Concerns: UI components focus on rendering, hooks handle logic

Template Processing Pipeline

Template (HBS) + Data (JSON) + Layout (HTML) + Styles (CSS)
                    ↓
            Handlebars.compile()
                    ↓
            Template Rendering
                    ↓
            Layout Application (if enabled)
                    ↓
            CSS Injection
                    ↓
            Final HTML Output

Component Architecture Breakdown

1. Layout Components

  • Header - Application controls (auto-play, layout, theme, reset)
  • Background - Animated background elements
  • MainContent - Main content wrapper with left/right panels

2. Editor Components

  • LeftPanel - Contains the editor interface and tab navigation
  • TabNavigation - Manages tab switching and shows save status
  • EditorPanel - Handles tab content switching with animations
  • MonacoEditor - Reusable Monaco editor with file import support

3. Preview Components

  • RightPanel - Contains the HTML preview panel
  • PreviewPanel - Handles error display and HTML rendering

4. State Management (Custom Hooks)

  • useEditor - Centralizes all editor state and Handlebars compilation
  • useTheme - Manages theme state and Supabase persistence

2. Handlebars Integration

  • Custom Helpers: formatDate, eq, gt, lt
  • Layout Support: Conditional layout application based on useLayout state
  • Error Handling: Graceful fallback for compilation errors
  • Real-time Updates: Automatic recompilation on content changes

3. Monaco Editor Configuration

  • Language Support: Handlebars, HTML, CSS, JSON
  • Editor Options: Syntax highlighting, auto-completion, minimap disabled
  • Keyboard Shortcuts: Custom Ctrl+S handling to prevent browser defaults
  • Theme Integration: Dark/light theme support

🎯 Code Quality & Maintainability

Refactoring Benefits

The application has been refactored from a monolithic 1000-line component into a clean, maintainable architecture:

  • Before: Single file with mixed concerns (1000+ lines)
  • After: 9 focused components + 2 custom hooks + utilities (~93 lines main component)

Architecture Principles

  • Single Responsibility: Each component has one clear purpose
  • Separation of Concerns: UI, logic, and utilities are separate
  • Props Down, Events Up: Clean data flow between components
  • Reusable Components: Components can be shared and tested independently
  • Custom Hooks: Business logic extracted into reusable hooks

Production Readiness

βœ… Maintainable: Easy to debug, test, and modify
βœ… Scalable: New features can be added without touching existing code
βœ… Professional: Follows React best practices and industry standards
βœ… Team-Friendly: Multiple developers can work on different components
βœ… Performance: Better code splitting and optimization opportunities

4. CSS Injection System

  • Smart Placement: Styles automatically inserted into <head> for layouts
  • Fallback Handling: Styles prepended to template output when no layout
  • Real-time Updates: CSS changes immediately reflected in preview

5. Persistence Layer

  • Flexible Storage Architecture: Service-based storage with multiple backend support
  • Storage Provider: Supabase (exclusive)
  • Automatic Data Migration: Seamless data persistence in Supabase
  • Preference Storage: Theme and layout settings persisted
  • Auto-save Triggers: Save on every content change
  • Manual Save: Ctrl+S shortcut for immediate persistence

File Structure & Organization

app/
β”œβ”€β”€ page.tsx              # Main application component
β”œβ”€β”€ layout.tsx            # Root layout with providers
β”œβ”€β”€ globals.css           # Global styles and Tailwind
β”œβ”€β”€ metadata.ts           # SEO and app metadata
└── manifest.ts           # PWA manifest
components/
β”œβ”€β”€ ui/                   # Reusable UI components
β”‚   β”œβ”€β”€ button.tsx        # Custom button component
β”‚   β”œβ”€β”€ card.tsx          # Glassmorphic card component
β”‚   └── separator.tsx     # Visual separator component
β”œβ”€β”€ error-boundary.tsx    # Error handling component
β”œβ”€β”€ loading.tsx           # Loading state component
└── providers.tsx         # Client-side providers wrapper

Technology Stack

  • Frontend Framework: Next.js 14 with App Router
  • UI Library: React 18 with TypeScript
  • Styling: Tailwind CSS with custom dark theme
  • Code Editor: Monaco Editor (VS Code engine)
  • Templating: Handlebars.js for template compilation
  • Animations: Framer Motion for smooth transitions
  • State Management: React hooks with Supabase persistence
  • Build Tool: Webpack with custom configurations

Key Functions & Methods

Template Compilation

useEffect(() => {
  if (!isPlaying) return
  
  try {
    const parsedData = JSON.parse(data)
    const templateFn = Handlebars.compile(template)
    const templateResult = templateFn(parsedData)
    
    let result = templateResult
    
    if (useLayout) {
      const layoutData = { ...parsedData, body: templateResult }
      const layoutFn = Handlebars.compile(layout)
      result = layoutFn(layoutData)
    }
    
    if (styles.trim()) {
      const styleTag = `<style>\n${styles}\n</style>`
      if (useLayout) {
        result = result.replace('</head>', `${styleTag}\n</head>`)
      } else {
        result = styleTag + '\n' + result
      }
    }
    
    setCompiledHtml(result)
    setError('')
  } catch (err) {
    setError(err instanceof Error ? err.message : 'Unknown error')
    setCompiledHtml('')
  }
}, [template, data, layout, styles, useLayout, isPlaying])

Auto-save System

const saveToStorage = (key: string, value: string) => {
  try {
    localStorage.setItem(key, value)
    setLastSaved(new Date())
  } catch (err) {
    console.warn('Failed to save to localStorage:', err)
  }
}

Keyboard Shortcut Handling

useEffect(() => {
  const handleKeyDown = (e: KeyboardEvent) => {
    if ((e.ctrlKey || e.metaKey) && e.key === 's') {
      e.preventDefault()
      e.stopPropagation()
      manualSave()
      return false
    }
  }
  
  document.addEventListener('keydown', handleKeyDown, true)
  return () => document.removeEventListener('keydown', handleKeyDown, true)
}, [template, data, layout, styles])

User Workflow

  1. Setup: Choose between layout and non-layout mode
  2. Template Creation: Write Handlebars templates in the body tab
  3. Data Input: Provide JSON data for template variables
  4. Layout Design: Create HTML structure with {{{body}}} placeholder
  5. Styling: Add custom CSS for visual customization
  6. Preview: See real-time results in the preview panel
  7. Iteration: Make changes and see immediate updates
  8. Export: Copy final HTML or save work automatically

Error Handling Strategy

  • Compilation Errors: Clear error messages with syntax highlighting
  • JSON Validation: Automatic parsing with fallback error display
  • Graceful Degradation: Preview shows error state instead of crashing
  • User Feedback: Visual indicators for error states

Performance Optimizations

  • Debounced Updates: Efficient re-rendering on content changes
  • Monaco Editor: Optimized code editing performance
  • CSS-in-JS: Efficient style injection without DOM manipulation
  • Lazy Loading: Suspense boundaries for better initial load times

πŸš€ Getting Started

Prerequisites

  • Node.js 18+
  • pnpm (recommended) or npm

Project Structure

HBS Parser/
β”œβ”€β”€ app/                    # Next.js app directory
β”‚   β”œβ”€β”€ page.tsx           # Main page component (93 lines)
β”‚   β”œβ”€β”€ layout.tsx         # Root layout
β”‚   └── globals.css        # Global styles
β”œβ”€β”€ components/             # Reusable UI components
β”‚   β”œβ”€β”€ layout/            # Layout components
β”‚   β”œβ”€β”€ editor/            # Editor components
β”‚   β”œβ”€β”€ preview/           # Preview components
β”‚   └── index.ts           # Component exports
β”œβ”€β”€ lib/                   # Utilities and hooks
β”‚   β”œβ”€β”€ hooks/             # Custom React hooks
β”‚   └── utils/             # Utility functions
└── types/                 # TypeScript type definitions

Development Workflow

  1. Component Development: Work on individual components in isolation
  2. Hook Logic: Business logic is centralized in custom hooks
  3. State Management: Clean data flow with props and event handlers
  4. Testing: Each component and hook can be tested independently

Installation

git clone https://github.com/ankurrokad/handlebar-parse.git
cd handlebar-parse
pnpm install
pnpm dev

Usage

  1. Open the app in your browser
  2. Switch between tabs to edit different content types
  3. Write Handlebars templates with live preview
  4. Add JSON data for template variables
  5. Customize with CSS for styling
  6. Use Ctrl+S to save your work
  7. Toggle layout mode as needed

Component Development

  • Adding New Features: Create new components in appropriate directories
  • Modifying Logic: Update custom hooks for business logic changes
  • Styling Changes: Modify component-specific styles or global CSS
  • Testing: Test individual components and hooks in isolation

πŸ”§ Configuration

Environment Variables

  • No environment variables required for basic functionality
  • Configure metadataBase in app/metadata.ts for production deployment

Customization

  • Theme Colors: Modify tailwind.config.js for custom color schemes
  • Editor Options: Adjust Monaco Editor settings in app/page.tsx
  • Handlebars Helpers: Add custom helpers in the useEffect hook

πŸ“± Browser Support

  • Modern Browsers: Chrome 90+, Firefox 88+, Safari 14+, Edge 90+
  • Features: ES2020, CSS Grid, Flexbox, Supabase
  • Fallbacks: Graceful degradation for older browsers

🀝 Contributing

Development Guidelines

  1. Fork the repository
  2. Create a feature branch
  3. Follow the component architecture:
    • UI changes β†’ Modify components
    • Logic changes β†’ Update custom hooks
    • Utility functions β†’ Add to lib/utils
  4. Test thoroughly - Each component can be tested independently
  5. Submit a pull request

Code Quality Standards

  • Single Responsibility: Each component should have one clear purpose
  • Props Interface: Define clear TypeScript interfaces for all props
  • Event Handling: Use consistent event handler patterns
  • Error Boundaries: Implement proper error handling
  • Performance: Consider React.memo for expensive components

πŸ†˜ Support

For issues, questions, or contributions:

  • Open an issue on GitHub
  • Check the documentation above
  • Review the code structure and comments

Built with ❀️ for the Handlebars community

About

Resources

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors