PHPackages                             artisanpack-ui/visual-editor - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Templating &amp; Views](/categories/templating)
4. /
5. artisanpack-ui/visual-editor

ActiveLibrary[Templating &amp; Views](/categories/templating)

artisanpack-ui/visual-editor
============================

A Gutenberg-powered visual editor for Laravel — post editor, site editor, and Blade/React/Vue block renderers.

1.3.0(2w ago)0100[30 issues](https://github.com/ArtisanPack-UI/visual-editor/issues)[1 PRs](https://github.com/ArtisanPack-UI/visual-editor/pulls)GPL-3.0-or-laterTypeScriptPHP ^8.2CI passing

Since Jun 5Pushed 1w agoCompare

[ Source](https://github.com/ArtisanPack-UI/visual-editor)[ Packagist](https://packagist.org/packages/artisanpack-ui/visual-editor)[ RSS](/packages/artisanpack-ui-visual-editor/feed)WikiDiscussions main Synced 1w ago

READMEChangelog (8)Dependencies (27)Versions (12)Used By (0)

ArtisanPack UI Visual Editor
============================

[](#artisanpack-ui-visual-editor)

A Gutenberg-powered visual editor for Laravel applications. Brings the WordPress block editor to any Eloquent model, plus a full site editor for templates, template parts, global styles, navigation menus, and patterns.

V1.0 ships:

- **Post editor** — block-based content editing on any model that opts in via the `HasBlockContent` trait.
- **Site editor** — templates, template parts, theme.json-backed global styles, navigation menus, and patterns; mounted at `/visual-editor/site`.
- **42 forked core blocks** under the `artisanpack/*` namespace. `core/*` markup pasted from upstream auto-converts on insert.
- **Icon block** (`artisanpack/icon`, v1.1) — Font Awesome 6 Free bundled, custom SVG paste with server-side sanitization, and admin upload for licensed sets (e.g. Font Awesome Pro). See [`docs/blocks/Icon-Block.md`](docs/blocks/Icon-Block.md).
- **Three renderer packages** — Blade (server-side), React, and Vue — for rendering saved block content on the public site.
- **First-class pairing** with [`artisanpack-ui/cms-framework`](https://github.com/ArtisanPack-UI/cms-framework)for Posts, Pages, site-meta, navigation, and global-styles persistence. Both packages remain usable standalone.

Full documentation: see [`docs/`](docs/). Start with [Quick Start](docs/Quick-Start.md), or browse the [documentation home](docs/home.md) for the full surface.

---

Installation
------------

[](#installation)

```
composer require artisanpack-ui/visual-editor
php artisan migrate
```

For the site editor (recommended for most apps):

```
composer require artisanpack-ui/cms-framework
php artisan migrate
```

See the [Installation Guide](docs/Installation-Guide.md) and [Quick Start](docs/Quick-Start.md) for the full setup.

---

Version compatibility
---------------------

[](#version-compatibility)

The visual-editor and `artisanpack-ui/cms-framework` packages ship as a version pair — both packages need to be present, and both need to be on a compatible major version, for the site-editor integration to work. Install one without the other and the site-editor's install gate (#432) surfaces a "cms-framework required" page instead of mounting.

visual-editorcms-frameworkNotesv1.xv1.xSite-editor integration (this release)v0.xv0.xPre-v1 — no site-editor integrationBumping the major on either package without bumping the partner is unsupported.

---

Peer dependencies
-----------------

[](#peer-dependencies)

The editor UI is built on [`@artisanpack-ui/react`](https://www.npmjs.com/package/@artisanpack-ui/react), which is styled with DaisyUI and Tailwind CSS. Host applications embedding the editor must have the following installed and loaded:

- `tailwindcss` `^4.0.0`
- `daisyui` `^5.0.0`

---

Usage
-----

[](#usage)

Add the `HasBlockContent` trait to any model and register it in `config/artisanpack/visual-editor.php`:

```
use ArtisanPackUI\VisualEditor\Concerns\HasBlockContent;

class Post extends Model
{
    use HasBlockContent;
}
```

```
// config/artisanpack/visual-editor.php
return [
    'resources' => [
        'posts' => App\Models\Post::class,
    ],
];
```

Mount the editor in a Blade view:

```

```

The site editor mounts automatically at `/visual-editor/site` when cms-framework is installed and the configured `SiteEditorAccessGate`permits the request.

See [`docs/post-editor/Blade-Component.md`](docs/post-editor/Blade-Component.md) for the full component reference and [`docs/site-editor.md`](docs/site-editor.md) for the site-editor surface.

---

Documentation
-------------

[](#documentation)

📚 **[Complete Documentation](docs/home.md)**

### Getting Started

[](#getting-started)

- **[Installation Guide](docs/Installation-Guide.md)** — Setup and configuration
- **[Quick Start](docs/Quick-Start.md)** — Ship your first post in under an hour
- **[Configuration](docs/Configuration.md)** — Full configuration reference

### Core Concepts

[](#core-concepts)

TopicDoc`HasBlockContent` + resource map[`docs/content-model.md`](docs/content-model.md)Blade / React / Vue renderers[`docs/renderers.md`](docs/renderers.md)Filters, actions, browser events[`docs/Hooks-and-Events.md`](docs/Hooks-and-Events.md)Migration &amp; WP import[`docs/migration.md`](docs/migration.md)Common problems[`docs/troubleshooting.md`](docs/troubleshooting.md)### Post Editor

[](#post-editor)

TopicDocSurface tour[`docs/post-editor.md`](docs/post-editor.md)Quick start[`docs/post-editor/Getting-Started.md`](docs/post-editor/Getting-Started.md)`` reference[`docs/post-editor/Blade-Component.md`](docs/post-editor/Blade-Component.md)Embedding in Livewire[`docs/post-editor/Livewire-Integration.md`](docs/post-editor/Livewire-Integration.md)Embedding in Inertia (React/Vue)[`docs/post-editor/Inertia-Integration.md`](docs/post-editor/Inertia-Integration.md)Theming editor chrome[`docs/post-editor/Theming.md`](docs/post-editor/Theming.md)### Site Editor

[](#site-editor)

TopicDocSurface tour[`docs/site-editor.md`](docs/site-editor.md)Quick start[`docs/site-editor/Getting-Started.md`](docs/site-editor/Getting-Started.md)`SiteEditorAccessGate` contract[`docs/site-editor/Access-Gate.md`](docs/site-editor/Access-Gate.md)Template hierarchy + parts[`docs/site-editor/Templates.md`](docs/site-editor/Templates.md)theme.json-backed global styles[`docs/site-editor/Global-Styles.md`](docs/site-editor/Global-Styles.md)Menus, locations, fallbacks[`docs/site-editor/Navigation.md`](docs/site-editor/Navigation.md)Synced vs unsynced patterns[`docs/site-editor/Patterns.md`](docs/site-editor/Patterns.md)### Blocks

[](#blocks)

TopicDocBlock library overview[`docs/blocks.md`](docs/blocks.md)Authoring custom blocks[`docs/blocks/Custom-Blocks.md`](docs/blocks/Custom-Blocks.md)Per-breakpoint values[`docs/blocks/Responsive-Design-Tools.md`](docs/blocks/Responsive-Design-Tools.md)Per-state overrides[`docs/blocks/State-Design-Tools.md`](docs/blocks/State-Design-Tools.md)### Developer Resources

[](#developer-resources)

- **[Developer Guide](docs/Developer-Guide.md)** — Extending the editor
- **[Hooks and Events](docs/Hooks-and-Events.md)** — Filters, actions, and browser events

---

Gutenberg adoption — transient shims
------------------------------------

[](#gutenberg-adoption--transient-shims)

The V1 editor adopts the upstream `@wordpress/*` packages. Some of those packages expect a WordPress backend that this package doesn't provide, so we ship temporary shims under `resources/js/visual-editor/vendor/`:

- **`core-data-shim.ts`** — aliased in `vite.config.ts` as `@wordpress/core-data`. Provides the entity registrations and selectors Gutenberg expects (`getEntityRecord`, `getEntityRecords`, resolvers, permissions stubs). Templates, template parts, navigation, patterns, global styles, attachments, and site-meta are wired through to the package's REST surface.
- **`media-upload-stub.tsx`** — registers `editor.MediaUpload` via `@wordpress/hooks` so the media-library picker on `core/image` is routed through a stub or the real `registerArtisanpackMediaBridge(MediaModal, uploadMedia)` bridge.

Both shims will be replaced over the V1.x release line as the cms-framework side surfaces real backings. Every selector or filter implemented here is one to re-verify against Gutenberg upgrades. See [`docs/troubleshooting.md`](docs/troubleshooting.md#2-core-data-shim-entities-and-missing-data).

---

Block defaults
--------------

[](#block-defaults)

V1 ships a frozen allow-list of forked blocks under the `artisanpack/*`namespace. The defaults in `config/artisanpack/visual-editor.php` expose every block that landed during the Phase I block fork — `@wordpress/block-library`'s `registerCoreBlocks()` is no longer called, and the editor registers only the in-package forks discovered under `resources/js/visual-editor/blocks/`. See [`docs/blocks.md`](docs/blocks.md)for the full block library overview and the `core/*` → `artisanpack/*`mapping.

The forked allow-list covers the content, media, layout, widget, entity, loop/feed, comments, query/pagination, and authentication clusters. Entity blocks (`artisanpack/post-*`, `artisanpack/site-*`, `artisanpack/template-part`, `artisanpack/navigation`) and the loop / feed cluster (`artisanpack/query`, `artisanpack/post-template`, `artisanpack/archives`, `artisanpack/categories`, `artisanpack/tag-cloud`) need an entity in scope to render meaningful content — pair the editor with [`artisanpack-ui/cms-framework`](https://github.com/ArtisanPack-UI/cms-framework)and they resolve against Posts / Pages / templates / site settings end-to-end. Standalone, they fall back to empty shells rather than crashing.

`disabled_blocks` is empty by default: with the I7 cutover (#415) the editor no longer registers any `core/*` block, so there's nothing to deny-list. New `@wordpress/block-library` releases similarly bring no new registrations into this package — additions land only when a fork is added to the in-package blocks directory and to the allow-list. `from:core/*` transforms ship on each fork so existing `core/*` markup pasted from upstream converts on insert.

Override the defaults by publishing the config to `config/artisanpack/visual-editor.php` and editing the `enabled_blocks`/ `disabled_blocks` arrays. The deny-list always wins over the allow-list.

---

Using with cms-framework
------------------------

[](#using-with-cms-framework)

The visual editor is fully usable standalone, but pairs with [`artisanpack-ui/cms-framework`](https://github.com/ArtisanPack-UI/cms-framework)to unlock:

- Editable `Post` and `Page` content out of the box.
- A real backing for `core/site-*` blocks (site title, tagline, logo, icon).
- Working `core/post-*`, `core/query`, taxonomy widget, and navigation blocks.
- Templates, template parts, patterns, global styles, and menus persisted via cms-framework's models.
- Seeded `visual_editor.*` permissions.

```
composer require artisanpack-ui/visual-editor artisanpack-ui/cms-framework
php artisan migrate
```

Both packages are loosely coupled — cms-framework's editor wiring is guarded by `class_exists(\ArtisanPackUI\VisualEditor\VisualEditor::class)`, so each remains usable on its own. See [`docs/site-editor/Getting-Started.md`](docs/site-editor/Getting-Started.md)for the site-editor pairing walkthrough.

---

Extensibility
-------------

[](#extensibility)

### `ap.visual-editor.resources`

[](#apvisual-editorresources)

Register slug → Eloquent model class mappings used by `/visual-editor/api/{resource}/{id}/content`. Filter contributions are merged with `config('artisanpack.visual-editor.resources')`; the static config wins on key collision so host-app overrides always take precedence. Models must use `ArtisanPackUI\VisualEditor\Concerns\HasBlockContent` — invalid entries surface as `InvalidArgumentException` on first request rather than at boot, so a contributor's standalone install never trips host boot.

```
addFilter('ap.visual-editor.resources', function (array $resources): array {
    return array_merge([
        'posts' => App\Models\Post::class,
    ], $resources);
});
```

Full contract: [`docs/content-model.md`](docs/content-model.md#2-the-resource-map) and [`docs/Hooks-and-Events.md`](docs/Hooks-and-Events.md#ap-visual-editor-resources).

### `ap.icons.register-icon-sets`

[](#apiconsregister-icon-sets)

Editor chrome icons resolve through `artisanpack-ui/icons`. Register additional icon sets in a service provider — see the [`artisanpack-ui/icons`](https://github.com/ArtisanPack-UI/icons) docs.

---

AI features
-----------

[](#ai-features)

The visual editor ships five optional AI-powered authoring affordances that build on top of the [`artisanpack-ui/ai`](https://github.com/ArtisanPack-UI/ai) foundation. All five default to *off* — hosts opt in by enabling the corresponding feature key from the AI package's settings surface, and each affordance honors that toggle before rendering.

Feature keyAgentWhat it does`visual_editor.suggest_next_block``ContentBlockSuggestionAgent`Inline "+ suggest" affordance ranks likely next blocks given the document so far.`visual_editor.suggest_layout``LayoutSuggestionAgent`Given a section's content + your available pattern library, ranks matching section patterns.`visual_editor.heading_hierarchy``HeadingHierarchyAgent`Audits the document for skipped levels, duplicate h1s, and ambiguous headings.`ai.alt_text``AltTextGenerationAgent` (from `ai`)Suggests accessibility-friendly alt text when an image block is added or its `src` changes and `alt` is empty.`ai.content_rewrite``ContentRewriteAgent` (from `ai`)Selection-toolbar / slash-command surface for "make shorter", "more formal", "reading level 6", etc.The first three agents live in this package (`src/Ai/Agents/`); the last two are cross-cutting agents consumed directly from `artisanpack-ui/ai`so the same prompt + feature toggle powers alt-text and content rewrites across every package that opts in.

### Server-side surface

[](#server-side-surface)

The features are auto-registered with the AI package's `FeatureRegistry`via `VisualEditorServiceProvider::aiFeatures()` — no manual wiring required. Each has a JSON endpoint under `/visual-editor/api/ai/*` for the React editor to hit:

```
GET  /visual-editor/api/ai/features             # { features: { : bool, ... } }
POST /visual-editor/api/ai/suggest-next-block
POST /visual-editor/api/ai/suggest-layout
POST /visual-editor/api/ai/alt-text
POST /visual-editor/api/ai/rewrite
POST /visual-editor/api/ai/heading-hierarchy

```

Blade / Livewire hosts can consume the same triggers through the shipped Livewire component `artisanpack-visual-editor.ai.tools`, which listens for `ap-ve-ai:*` browser events and re-dispatches results as `ap-ve-ai:{feature}:{status}`.

### React surface

[](#react-surface)

```
import {
    createAiApiClient,
    useAiFeatures,
    SuggestNextBlockButton,
    HeadingHierarchyPanel,
} from '../visual-editor/ai';

const client = createAiApiClient({ apiBase: '/visual-editor/api' });
const { isEnabled } = useAiFeatures(client);

{isEnabled('visual_editor.suggest_next_block') && (
     insertBlock(suggestion.block_type)}
    />
)}
```

Full component list: `resources/js/visual-editor/ai/index.ts`.

### Requirements

[](#requirements)

- `artisanpack-ui/ai` ^1.0 installed and configured with credentials.
- The individual feature toggle enabled (default: off) from the AI settings admin surface.
- CSRF middleware active on the `/visual-editor/api/*` route group so the shipped JS client's `X-CSRF-TOKEN` header is honored.

Every affordance surfaces as a **suggestion** — never an automatic mutation. Accepting a suggestion is always explicit user action, per the AI RFC.

---

i18n
----

[](#i18n)

Editor strings use `@wordpress/i18n` with the `artisanpack-visual-editor`text domain. The domain is initialized via `bootI18n()` in `resources/js/visual-editor/vendor/i18n.ts`.

Regenerate the placeholder `.pot` catalog with:

```
npm run i18n:extract
```

The extractor scans `resources/js/visual-editor/**/*.{ts,tsx}` for `__/_x/_n/_nx` calls bound to the text domain and writes `languages/artisanpack-visual-editor.pot`.

---

Contributing
------------

[](#contributing)

As an open source project, this package is open to contributions from anyone. Please [read through the contributing guidelines](CONTRIBUTING.md) to learn more about how you can contribute to this project.

###  Health Score

45

—

FairBetter than 91% of packages

Maintenance97

Actively maintained with recent releases

Popularity12

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity53

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 99.7% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~6 days

Total

6

Last Release

17d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/ba2a2c40c9a93470595cd10701d2291434f3a7db61862d9700a9e69e31608c6c?d=identicon)[JacobMartellaWebDesign](/maintainers/JacobMartellaWebDesign)

---

Top Contributors

[![ViewFromTheBox](https://avatars.githubusercontent.com/u/8247489?v=4)](https://github.com/ViewFromTheBox "ViewFromTheBox (692 commits)")[![claude](https://avatars.githubusercontent.com/u/81847?v=4)](https://github.com/claude "claude (2 commits)")

---

Tags

block-editorlaravellaravel-packagelivewirepage-builderphpvisual-editorwysiwyg

###  Code Quality

TestsPest

### Embed Badge

![Health badge](/badges/artisanpack-ui-visual-editor/health.svg)

```
[![Health](https://phpackages.com/badges/artisanpack-ui-visual-editor/health.svg)](https://phpackages.com/packages/artisanpack-ui-visual-editor)
```

###  Alternatives

[craftcms/cms

Craft CMS

3.6k3.6M3.2k](/packages/craftcms-cms)[moonshine/moonshine

Laravel administration panel

1.3k253.1k86](/packages/moonshine-moonshine)[tallstackui/tallstackui

TallStackUI is a powerful suite of Blade components that elevate your workflow of Livewire applications.

728176.2k14](/packages/tallstackui-tallstackui)[pressbooks/pressbooks

Pressbooks is an open source book publishing tool built on a WordPress multisite platform. Pressbooks outputs books in multiple formats, including PDF, EPUB, web, and a variety of XML flavours, using a theming/templating system, driven by CSS.

45444.2k1](/packages/pressbooks-pressbooks)[ublabs/blade-simple-icons

A package to easily make use of Simple Icons in your Laravel Blade views.

1963.4k](/packages/ublabs-blade-simple-icons)[technikermathe/blade-lucide-icons

A package to easily make use of Lucide icons in your Laravel Blade views.

18421.4k11](/packages/technikermathe-blade-lucide-icons)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
