A premium, minimal drag-and-drop page builder built with React, dnd-kit, and Tailwind CSS.
- Three block types: Heading (H1/H2/H3), Text paragraph, Image (URL + caption + alt)
- Drag & drop reordering via dnd-kit with smooth animations and drag overlay
- Inline editing — click any block to edit directly
- Duplicate blocks — one-click clone of any block
- Delete blocks with confirmation
- Auto-save to localStorage — persists across page refreshes
- Clear all with double-confirm safety check
- Empty state with quick-add shortcuts
- Invalid image URL handling with visual error state
| Layer | Choice |
|---|---|
| Framework | React 18 (Vite) |
| Language | JavaScript (no TypeScript) |
| Styling | Tailwind CSS v3 |
| Drag & Drop | dnd-kit (core + sortable + modifiers) |
| State | useReducer |
| Persistence | localStorage |
| Fonts | DM Sans, DM Mono, Syne (Google Fonts) |
src/
components/
Sidebar.jsx — Left panel with block-type buttons
Canvas.jsx — DnD context, sortable list, empty state
BlockWrapper.jsx — Drag handle, type label, delete/duplicate actions
HeaderBlock.jsx — Editable heading with H1/H2/H3 switcher
TextBlock.jsx — Auto-resizing textarea paragraph
ImageBlock.jsx — URL input, preview, alt text, caption
hooks/
useBlocks.js — useReducer for all block CRUD + reorder
utils/
storage.js — localStorage load/save/clear helpers
App.jsx — Root layout: sidebar + topbar + canvas
main.jsx — React entry point
- State lives in
useBlocksas{ blocks: [...] }, managed byuseReducer - Every state change triggers a
useEffectthat callssaveBlocks()to localStorage - On mount,
loadBlocks()hydrates initial state from storage Canvas.jsxwraps blocks inDndContext+SortableContext; eachBlockWrapperusesuseSortable- On drag end,
arrayMovereorders the array and dispatchesREORDER_BLOCKS - Each block type component receives
content+onChange— it's purely controlled
npm install
npm run devLink To Vercel https://vercel.com/azhanhashmis-projects/notesly
npm run build
# drag the dist/ folder to vercel.com/new, or:
npx vercel --prod