Skip to Content
Apps & ServicesTheme Editor

Theme Editor

Overview

The Theme Editor (editor.siyahfy.com) is a visual drag-and-drop editor that allows vendors to customize their storefront theme without writing any code. Vendors can rearrange sections, edit content, adjust styles, configure color schemes, and see changes in a live preview — all from a browser-based interface similar to Shopify’s theme customizer.

Users: Vendors (store owners) and Staff members with theme access

Tech Stack

TechnologyVersionPurpose
Next.js16.xReact framework with App Router
React19.xUI library
TypeScript5.xType safety
Zustand5.xState management
dnd-kit6.x / 10.xDrag-and-drop for section reordering
TipTap3.xInline rich text editing
CodeMirror6.xCSS code editing
Tailwind CSS4.xUtility-first styling
Polaris Icons9.xConsistent iconography
canvas-confetti1.xSave celebration animation

Folder Structure

editor.siyahfy.com/ ├── app/ │ ├── layout.tsx # Root layout │ ├── page.tsx # Landing / redirect │ ├── editor/ │ │ └── [store_slug]/ # Editor workspace (per store) │ │ └── page.tsx # Main editor page │ └── onboarding/ │ └── [store]/ # New store onboarding editor │ └── page.tsx ├── components/ │ ├── editor/ # Editor panel components │ │ ├── SectionSidebar.tsx # Left sidebar: section list │ │ ├── SidebarPanels.tsx # Panel switcher │ │ ├── SectionSettings.tsx # Section-level settings form │ │ ├── SubItemSettings.tsx # Block/sub-item settings │ │ ├── WidgetSettings.tsx # Widget configuration │ │ ├── WidgetsPanel.tsx # Widget library browser │ │ ├── WidgetPalette.tsx # Drag-to-add widget palette │ │ ├── ThemeSettingsPanel.tsx # Global theme settings │ │ ├── HeaderSettings.tsx # Header configuration │ │ ├── CheckoutSettingsPanel.tsx # Checkout page settings │ │ ├── BackgroundPanel.tsx # Section background controls │ │ ├── ButtonStylePanel.tsx # Button style configuration │ │ ├── ProductCardSettings.tsx # Product card appearance │ │ ├── ColorSchemePicker.tsx # Color scheme selector │ │ ├── ColorPickerWithReset.tsx # Color picker with reset │ │ ├── SpacingBoxInput.tsx # Margin/padding visual editor │ │ ├── StepperInput.tsx # Numeric stepper input │ │ ├── MediaLibraryModal.tsx # Image upload & selection │ │ ├── LinkPicker.tsx # URL/page link selector │ │ ├── ProductPickerModal.tsx # Product picker for sections │ │ ├── CollectionPickerModal.tsx # Collection picker │ │ ├── PageSelector.tsx # Page selection dropdown │ │ ├── AddSectionModal.tsx # Add new section dialog │ │ ├── StructurePicker.tsx # Column layout picker │ │ ├── CssCodeEditor.tsx # Custom CSS editor (CodeMirror) │ │ ├── VersionHistoryPanel.tsx # Theme version history │ │ ├── EditorTopBar.tsx # Top toolbar (save, preview, publish) │ │ ├── PreviewFrame.tsx # Live preview iframe │ │ ├── IconRail.tsx # Left icon navigation rail │ │ ├── ContextMenu.tsx # Right-click context menu │ │ ├── CustomSectionSettings.tsx # Custom section config │ │ └── SessionExpiredModal.tsx # Auth expiry handler │ ├── preview/ # Preview renderers │ │ ├── SectionRenderer.tsx # Routes section type to component │ │ ├── HeaderPreview.tsx # Header live preview │ │ ├── FooterPreview.tsx # Footer live preview │ │ ├── HeroBanner.tsx # Hero banner preview │ │ ├── FeaturedCollection.tsx # Featured collection preview │ │ ├── RichText.tsx # Rich text section preview │ │ ├── Newsletter.tsx # Newsletter section preview │ │ ├── AnnouncementBar.tsx # Announcement bar preview │ │ ├── CartDrawer.tsx # Cart drawer preview │ │ ├── CustomSectionPreview.tsx # Custom section renderer │ │ ├── ProductDetailPreview.tsx # Product page preview │ │ ├── CollectionTemplatePreview.tsx # Collection page preview │ │ ├── CheckoutContentPreview.tsx # Checkout page preview │ │ ├── AccountContentPreview.tsx # Account page preview │ │ ├── CartContentPreview.tsx # Cart page preview │ │ ├── SearchModal.tsx # Search overlay preview │ │ └── widgets/ # Widget preview renderers │ ├── EditorHeader.tsx # App header bar │ └── ProfileDropdown.tsx # User profile menu ├── hooks/ │ ├── useInlineEditable.ts # Inline text editing in preview │ └── useIsMobile.ts # Responsive detection ├── lib/ │ ├── editor-store.ts # Zustand store (main editor state) │ ├── section-schemas.ts # Section type definitions │ ├── widget-schemas.ts # Widget type definitions │ ├── column-style-schema.ts # Column layout schemas │ ├── structure-layouts.ts # Pre-defined column structures │ ├── color-schemes.ts # Color scheme definitions │ ├── hover-animations.ts # Hover animation presets │ ├── icon-library.tsx # Icon set for widgets │ ├── auth.ts # Authentication helpers │ └── tiptap-title-chip.ts # TipTap extension for title chips └── public/ # Static assets

How the Visual Editor Works

The editor follows a three-panel layout:

┌─────────────────────────────────────────────────────────┐ │ EditorTopBar (Save, Undo, Redo, Preview, Publish) │ ├────┬───────────────┬────────────────────────────────────┤ │Icon│ SectionSidebar│ PreviewFrame │ │Rail│ (drag-to- │ (live iframe or │ │ │ reorder │ in-app preview) │ │ │ sections) │ │ │ │ │ │ │ │ SectionSettings │ │ │ (when a │ │ │ │ section is │ │ │ │ selected) │ │ └────┴───────────────┴────────────────────────────────────┘

Architecture

  1. Zustand Store (lib/editor-store.ts) — Holds the entire editor state: section list, selected section, theme settings, color schemes, undo/redo history, and dirty-state tracking.

  2. Section Schemas (lib/section-schemas.ts) — Define what settings each section type exposes (text fields, color pickers, toggles, sliders, image uploads). The settings panel is auto-generated from these schemas.

  3. Preview Rendering — The SectionRenderer component reads the section type and dispatches to the correct preview component (HeroBanner, FeaturedCollection, etc.). Changes in the settings panel update the Zustand store, which triggers an immediate re-render in the preview.

  4. Drag-and-Drop — Uses @dnd-kit/core and @dnd-kit/sortable to let vendors reorder sections by dragging them in the sidebar list.

Section Schema System

Each section type has a schema defining its settings, organized by tabs:

// Example section schema structure { type: 'hero-banner', name: 'Hero Banner', icon: 'ImageIcon', max_blocks: 5, settings: [ { key: 'heading', type: 'text', label: 'Heading', tab: 'content' }, { key: 'subheading', type: 'text', label: 'Subheading', tab: 'content' }, { key: 'image', type: 'image', label: 'Background Image', tab: 'content' }, { key: 'button_text', type: 'text', label: 'Button Text', tab: 'content' }, { key: 'button_link', type: 'link', label: 'Button Link', tab: 'content' }, { key: 'color_scheme', type: 'color_scheme', label: 'Color Scheme', tab: 'style' }, { key: 'height', type: 'range', label: 'Height', min: 300, max: 800, tab: 'style' }, ], blocks: [ { type: 'slide', name: 'Slide', settings: [ { key: 'image', type: 'image', label: 'Slide Image' }, { key: 'heading', type: 'text', label: 'Heading' }, ] } ] }

Setting types include: text, textarea, richtext, image, link, color, color_scheme, range, select, toggle, number, product, collection, and page.

Widget System

Widgets are drag-and-drop elements that can be placed inside Custom Sections. The widget palette includes 27+ widgets:

WidgetDescription
HeadingWidgetConfigurable heading (H1-H6)
TextWidgetRich text block
ImageWidget / ImageBoxWidgetImage with optional overlay
ImageGalleryWidgetMulti-image gallery
ButtonWidgetCall-to-action button
VideoWidgetEmbedded video player
IconWidget / IconListWidgetIcon displays
DividerWidgetHorizontal divider
SpacerWidgetVertical spacing
AccordionWidgetExpandable FAQ/content
TabsWidgetTabbed content sections
CounterWidgetAnimated number counter
TestimonialWidgetCustomer testimonial card
ProductsWidgetProduct grid/carousel
CategoriesWidgetCategory display
SocialIconsWidgetSocial media links
GoogleMapsWidgetEmbedded map
StarRatingWidgetStar rating display
ProgressBarWidgetProgress bar
MenuWidgetNavigation menu
InnerSectionWidgetNested layout container

API Communication

The editor communicates with the backend through authenticated API calls:

// Typical pattern const response = await fetch(`${API_URL}/api/theme-editor/save`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}` }, body: JSON.stringify({ store_slug: storeSlug, sections: editorStore.sections, settings: editorStore.themeSettings, }) });

Key API endpoints used:

  • GET /api/theme-editor/load/:store_slug — Load theme configuration
  • POST /api/theme-editor/save — Save theme changes
  • POST /api/files/upload — Upload media files
  • GET /api/storefront/products — Fetch products for pickers
  • GET /api/storefront/collections — Fetch collections for pickers

Key Routes

RouteDescription
/editor/[store_slug]Main editor workspace for a store
/onboarding/[store]First-time theme setup during onboarding

State Management

All editor state lives in a single Zustand store (lib/editor-store.ts). Key state includes:

  • sections — Array of section objects with their settings
  • selectedSectionId — Currently selected section for editing
  • themeSettings — Global theme settings (colors, fonts, spacing)
  • colorSchemes — Available color scheme definitions
  • undoStack / redoStack — Undo/redo history
  • isDirty — Whether unsaved changes exist
  • isSaving — Save operation in progress

Environment Variables

VariableDescription
NEXT_PUBLIC_API_URLBackend API base URL
NEXT_PUBLIC_STOREFRONT_URLStorefront preview URL
NEXT_PUBLIC_EDITOR_URLEditor URL (self-reference)
NEXT_PUBLIC_DASHBOARD_URLDashboard URL for navigation