A modern, extensible drag-and-drop page builder for Vue 3
Live Demo β’ Documentation β’ Examples β’ Contributing
BinaryCastle Page Builder is a powerful, extensible visual page builder built with Vue 3, TypeScript, and modern web technologies. It provides an intuitive drag-and-drop interface for creating dynamic web pages with real-time preview, rich text editing, and customizable components.
- π― Drag & Drop Interface - Intuitive visual editor with real-time preview
- π§© Extensible Components - Built-in blocks (Text, Button, Columns, HTML) with custom component support
- π Rich Text Editing - Powered by TipTap with formatting controls and bubble menus
- π» Code Editor - Integrated CodeMirror for HTML/CSS editing
- π¨ Visual Customization - Color pickers, style controls, and CSS class management
- π± Responsive Design - Mobile-first approach with device preview modes
- π§ TypeScript Support - Full type safety and IntelliSense support
- β‘ Modern Stack - Vue 3 Composition API, Vite, and Tailwind CSS
- πͺ Live Preview - Real-time page preview with seamless editing experience
- ποΈ Layout System - Flexible column layouts with nested component support
npm install @binarycastle/page-builderyarn add @binarycastle/page-builderpnpm add @binarycastle/page-builder<script setup>
import { PageBuilder } from "@binarycastle/page-builder"
import "@binarycastle/page-builder/dist/bc-page-builder.css"
const handleSave = (data) => {
console.log('Page data:', data)
// data.renderList contains the page structure
// data.meta contains the page metadata
}
</script>
<template>
<PageBuilder @onSave="handleSave" />
</template><script setup>
import { PageBuilder } from "@binarycastle/page-builder"
const initialContent = [
{
id: "text-block-1",
name: "text",
options: {
text: "<h1>Welcome to my page!</h1>",
hasContainer: true
}
}
]
const handleSave = (data) => {
// Save your page data
}
</script>
<template>
<PageBuilder
:renderList="initialContent"
@onSave="handleSave"
/>
</template><script setup>
import { PagePreview } from "@binarycastle/page-builder"
const pageContent = [
// Your page structure
]
</script>
<template>
<PagePreview :renderList="pageContent" />
</template>The main page builder component with full editing capabilities.
Props:
cssUrl?: string- External CSS file URLrenderList?: Block[]- Initial page contentmeta?: Array<Record<string, string>>- Page metadatapageTitle?: string- Page title
Events:
@onSave- Emitted when user saves the page
Render-only component for displaying pages without editing interface.
Props:
renderList: Block[]- Page content to rendercssUrl?: string- External CSS file URL
Rich text editor with formatting controls, alignment, and styling options.
// Usage in custom registration
{
type: 'element',
name: 'text',
title: 'Text',
description: 'Rich text with formatting'
}Interactive buttons with customizable actions, styling, and alignment.
// Features:
// - Text customization
// - External/internal links
// - Alignment controls
// - Custom CSS classes and stylesFlexible layout system supporting 1-6 columns with individual styling.
// Features:
// - Up to 6 columns
// - Individual column styling
// - Nested component support
// - Responsive designRaw HTML and CSS editor for advanced customization.
// Features:
// - CodeMirror HTML editor
// - Scoped CSS styling
// - Live previewBase wrapper for creating custom block components.
<script setup lang="ts">
import { BasePreview, Block } from "@binarycastle/page-builder"
interface Props {
blockInfo: Block
inEditor?: boolean
}
defineProps<Props>()
</script>
<template>
<BasePreview :inEditor="inEditor">
<h1>Your custom content</h1>
</BasePreview>
</template>Base wrapper for creating block option panels.
<script setup lang="ts">
import { BaseOption, OptionWidget, Block } from "@binarycastle/page-builder"
interface Props {
blockInfo: Block
}
defineProps<Props>()
</script>
<template>
<BaseOption title="Custom Block">
<OptionWidget title="Setting 1">
<!-- Your controls -->
</OptionWidget>
</BaseOption>
</template>ColorInput- Color picker componentSliderToggle- Toggle switch componentRichTextEditor- Standalone rich text editorCodeMirrorEditor- Code editor component
<script setup>
import { PageBuilder, registerBlock } from "@binarycastle/page-builder"
import CustomComponent from "./CustomComponent.vue"
import CustomOptionComponent from "./CustomOptionComponent.vue"
// Register your custom block
registerBlock({
type: 'element',
component: CustomComponent,
optionComponent: CustomOptionComponent,
options: {
// Default options for your block
customProperty: 'default value'
},
title: 'Custom Block',
name: 'custom_block',
description: 'A custom component for special content',
previewImg: '/path/to/preview.png',
icon: '<svg>...</svg>' // SVG icon or HTML
})
</script>
<template>
<PageBuilder @onSave="handleSave" />
</template><!-- CustomComponent.vue -->
<script setup lang="ts">
import { BasePreview, Block } from "@binarycastle/page-builder"
interface CustomBlock extends Block {
options: {
customProperty: string
// ... other options
}
}
interface Props {
blockInfo: CustomBlock
inEditor?: boolean
}
defineProps<Props>()
</script>
<template>
<BasePreview :inEditor="inEditor">
<div>{{ blockInfo.options.customProperty }}</div>
</BasePreview>
</template><!-- CustomOptionComponent.vue -->
<script setup lang="ts">
import { BaseOption, OptionWidget } from "@binarycastle/page-builder"
interface Props {
blockInfo: CustomBlock
}
defineProps<Props>()
</script>
<template>
<BaseOption title="Custom Block Settings">
<OptionWidget title="Custom Property">
<input
v-model="blockInfo.options.customProperty"
class="bg-page-builder-input"
/>
</OptionWidget>
</BaseOption>
</template>The page builder uses Tailwind CSS with the bcpb: prefix to avoid conflicts with your application styles.
/* Your custom styles */
.my-custom-block {
background: linear-gradient(45deg, #ff6b6b, #4ecdc4);
padding: 2rem;
border-radius: 0.5rem;
}<template>
<BasePreview>
<div class="my-custom-block">
Content
</div>
</BasePreview>
</template>interface Block {
id: string
name: string
type: 'element' | 'layout' | 'ui-component'
options: Record<string, any>
children?: Block[][] // For layout blocks
}interface SaveData {
renderList: Block[]
meta: Array<Record<string, string>>
}{
"renderList": [
{
"id": "text-123",
"name": "text",
"type": "element",
"options": {
"text": "<h1>Hello World</h1>",
"hasContainer": true,
"backgroundColor": "#ffffff"
}
},
{
"id": "button-456",
"name": "button",
"type": "element",
"options": {
"text": "Click Me",
"buttonAction": {
"type": "external_link",
"url": "https://example.com"
}
}
}
],
"meta": [
{
"attitude": "property",
"name": "title",
"content": "My Awesome Page"
}
]
}# Clone the repository
git clone https://github.com/binary-castle/page-builder.git
cd page-builder
# Install dependencies
yarn install
# Start development server
yarn dev
# Build for production
yarn buildsrc/
βββ lib/
β βββ block-components/ # Built-in block components
β βββ controls/ # Form controls (ColorInput, SliderToggle)
β βββ editors/ # Text and code editors
β βββ layouts/ # Layout components
β βββ ui-components/ # UI component blocks
β βββ utils/ # Utilities and types
β βββ PageBuilder.vue # Main component
βββ scss/ # SCSS styles
βββ main.ts # Entry point
- Vue 3 with Composition API
- TypeScript for type safety
- Vite for fast development and building
- Tailwind CSS with custom prefix (
bcpb:) - TipTap for rich text editing
- CodeMirror for code editing
- Popper.js for tooltips and dropdowns
We welcome contributions from the community! Here's how you can help:
- Fork the repository
- Create a feature branch:
git checkout -b feature/amazing-feature - Make your changes
- Run tests:
yarn test(if applicable) - Commit your changes:
git commit -m 'Add amazing feature' - Push to the branch:
git push origin feature/amazing-feature - Open a Pull Request
- Follow the existing code style and conventions
- Add TypeScript types for new features
- Update documentation for new components
- Test your changes thoroughly
- Keep commits focused and descriptive
Please use the GitHub Issues page to report bugs or request features.
This project is licensed under the LGPL-3.0 License.
BinaryCastle Page Builder is developed and maintained by BinaryCastle.net, a company focused on creating modern web development tools and solutions.
- Website: binarycastle.net
- GitHub: github.com/binary-castle
- Issues: Report bugs or request features
- Vue.js - The progressive JavaScript framework
- TipTap - Headless editor framework
- CodeMirror - In-browser code editor
- Tailwind CSS - Utility-first CSS framework
- Vite - Next generation frontend tooling
Built with β€οΈ by the BinaryCastle team
β Star us on GitHub β’ π Report a bug β’ π‘ Request a feature
