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.
- 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
- 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
- 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
- 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
The application follows modern React best practices with a clean, maintainable architecture:
βββββββββββββββββββ βββββββββββββββββββ βββββββββββββββββββ
β Monaco Editor β β Handlebars.js β β Live Preview β
β (Input) βββββΆβ (Compiler) βββββΆβ (Output) β
βββββββββββββββββββ βββββββββββββββββββ βββββββββββββββββββ
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
β
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
- User Input β Monaco Editor captures changes in real-time
- State Update β Custom hooks manage state updates and trigger re-renders
- Handlebars Compilation β Template + Data + Layout compiled together
- CSS Injection β Custom styles automatically injected into output
- HTML Rendering β Final HTML displayed in preview panel
- Auto-save β All content automatically persisted to Supabase
useEditorHook: Centralizes all editor state and Handlebars compilation logicuseThemeHook: Manages theme state and storage persistenceuseStorageHook: 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 (HBS) + Data (JSON) + Layout (HTML) + Styles (CSS)
β
Handlebars.compile()
β
Template Rendering
β
Layout Application (if enabled)
β
CSS Injection
β
Final HTML Output
Header- Application controls (auto-play, layout, theme, reset)Background- Animated background elementsMainContent- Main content wrapper with left/right panels
LeftPanel- Contains the editor interface and tab navigationTabNavigation- Manages tab switching and shows save statusEditorPanel- Handles tab content switching with animationsMonacoEditor- Reusable Monaco editor with file import support
RightPanel- Contains the HTML preview panelPreviewPanel- Handles error display and HTML rendering
useEditor- Centralizes all editor state and Handlebars compilationuseTheme- Manages theme state and Supabase persistence
- Custom Helpers:
formatDate,eq,gt,lt - Layout Support: Conditional layout application based on
useLayoutstate - Error Handling: Graceful fallback for compilation errors
- Real-time Updates: Automatic recompilation on content changes
- 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
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)
- 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
β
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
- 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
- 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
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
- 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
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])const saveToStorage = (key: string, value: string) => {
try {
localStorage.setItem(key, value)
setLastSaved(new Date())
} catch (err) {
console.warn('Failed to save to localStorage:', err)
}
}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])- Setup: Choose between layout and non-layout mode
- Template Creation: Write Handlebars templates in the body tab
- Data Input: Provide JSON data for template variables
- Layout Design: Create HTML structure with
{{{body}}}placeholder - Styling: Add custom CSS for visual customization
- Preview: See real-time results in the preview panel
- Iteration: Make changes and see immediate updates
- Export: Copy final HTML or save work automatically
- 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
- 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
- Node.js 18+
- pnpm (recommended) or npm
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
- Component Development: Work on individual components in isolation
- Hook Logic: Business logic is centralized in custom hooks
- State Management: Clean data flow with props and event handlers
- Testing: Each component and hook can be tested independently
git clone https://github.com/ankurrokad/handlebar-parse.git
cd handlebar-parse
pnpm install
pnpm dev- Open the app in your browser
- Switch between tabs to edit different content types
- Write Handlebars templates with live preview
- Add JSON data for template variables
- Customize with CSS for styling
- Use Ctrl+S to save your work
- Toggle layout mode as needed
- 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
- No environment variables required for basic functionality
- Configure
metadataBaseinapp/metadata.tsfor production deployment
- Theme Colors: Modify
tailwind.config.jsfor custom color schemes - Editor Options: Adjust Monaco Editor settings in
app/page.tsx - Handlebars Helpers: Add custom helpers in the
useEffecthook
- Modern Browsers: Chrome 90+, Firefox 88+, Safari 14+, Edge 90+
- Features: ES2020, CSS Grid, Flexbox, Supabase
- Fallbacks: Graceful degradation for older browsers
- Fork the repository
- Create a feature branch
- Follow the component architecture:
- UI changes β Modify components
- Logic changes β Update custom hooks
- Utility functions β Add to lib/utils
- Test thoroughly - Each component can be tested independently
- Submit a pull request
- 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
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