Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Ueditor Laravel Package

ibrand/laravel-ueditor

Laravel integration for Baidu UEditor, making it easy to embed the rich-text editor in admin panels and forms. Includes configuration, asset publishing, and server-side upload/controller support so you can get UEditor running quickly in Laravel applications.

View on GitHub
Deep Wiki
Context7

Getting Started

1. Install and verify compatibility first. This is a low-traffic package (3 stars, 0 dependents), so check its composer.json constraints against your Laravel/PHP version before committing:

composer require ibrand/laravel-ueditor

Inspect vendor/ibrand/laravel-ueditor/composer.json for illuminate/support and php constraints. If you're on Laravel 10/11 or PHP 8.2+, expect to fork or vendor the source — most packages of this vintage target Laravel 5.x–6.x and use facades/helpers that were removed later.

2. Publish and read the service provider. The package almost certainly auto-registers a provider and bundles routes, a controller, a config file, and maybe UEditor's static assets:

php artisan vendor:publish --provider="Ibrand\UEditor\UEditorServiceProvider"
php artisan route:list | grep -i ueditor

Look first at:

  • src/Providers/*ServiceProvider.php — route registration, config merge, asset publishing tags
  • config/ueditor.php (published name may differ) — upload disk, path, allowed extensions, max size
  • The controller handling action=config, uploadimage, uploadfile, uploadvideo, listimage, catchimage
  • routes/*.php for the endpoint URI UEditor's JS will call as serverUrl

3. First use case: wire the editor into a Blade form. The package's job is the server side of UEditor; the client side is still UEditor's own JS bundle. Typical minimal wiring:

<form method="POST" action="/posts">
    @csrf
    <script id="editor" name="content" type="text/plain">{{ old('content', $post->content ?? '') }}</script>
    <button type="submit">Save</button>
</form>

<script src="{{ asset('vendor/ueditor/ueditor.config.js') }}"></script>
<script src="{{ asset('vendor/ueditor/ueditor.all.min.js') }}"></script>
<script>
  window.UEDITOR_CONFIG.serverUrl = '{{ route('ueditor.server') }}';
  const ue = UE.getEditor('editor');
</script>

Point serverUrl at the published route, submit the form, and confirm that pasting an image triggers a POST back to that route and drops a file under your configured disk. That round trip is the whole value of the package — everything else is configuration.

Implementation Patterns

Keep the upload endpoint behind auth and a dedicated route group. These packages usually register routes unconditionally in web middleware (or none at all). Override in a provider or route file:

Route::middleware(['web', 'auth', 'can:edit-posts'])
    ->group(base_path('vendor/ibrand/laravel-ueditor/routes/web.php'));

If the package's provider guards registration with config('ueditor.routes', true), disable it and declare your own routes pointing at the same controller — you keep the controller and lose the open upload endpoint.

Centralize storage in config, not in the controller. The pattern worth preserving is: the controller resolves a disk + path from config, and the UEditor response shape ({"state": "SUCCESS", "url": "...", "title": "...", "original": "..."}) is built from the stored file. If the package hardcodes public/uploads, refactor to:

// config/ueditor.php
'disk' => env('UEDITOR_DISK', 'public'),
'path' => 'uploads/ueditor/' . date('Y/m'),
'allowed_ext' => ['jpg','jpeg','png','gif','webp'],
'max_size' => 5 * 1024 * 1024,

Then the controller calls Storage::disk($disk)->putFileAs(...) and returns Storage::disk($disk)->url($path). This is the main refactor to make if the original uses move_uploaded_file() — it makes the package work with S3/R2 and keeps local dev aligned with prod.

Sanitize the HTML before it hits your DB. UEditor stores raw HTML in a TEXT/LONGTEXT column. The package will not sanitize for you:

$post->content = clean($request->input('content')); // mews/purifier or HTMLPurifier

Treat every saved editor body as untrusted — the embedded catchimage (remote image fetch) action is a classic SSRF vector if it's reachable unauthenticated.

Multiple editor instances: UEditor's serverUrl is global on window.UEDITOR_CONFIG. For two editors on one page with different upload policies, initialize each with UE.getEditor('id', { serverUrl: '...' }) per-instance rather than mutating the global, and give each its own route/controller if the storage targets differ.

Form lifecycle: UEditor renders into a <script type="text/plain"> element. On validation failure, re-render the old value inside that script tag before UE.getEditor() runs — otherwise the editor loads empty and users lose their content. If you use Livewire/Inertia, don't — UEditor mutates the DOM directly and fights both; use a plain form post or explicitly ue.setContent() in a hook.

Gotchas and Tips

  • UEditor is not CSRF-aware. Its XHR won't attach X-CSRF-TOKEN. Either exclude the upload route from VerifyCsrfToken (only acceptable if the route is auth-gated and rate-limited) or set window.UEDITOR_CONFIG.serverUrl through a wrapper that injects the header. Silent 419s are the #1 "uploads don't work" cause.
  • action=config must return valid JSON. UEditor's JS first GETs serverUrl?action=config to learn allowed extensions and paths. If your controller returns HTML (a redirect to login, a debug page, a 500), the editor fails with a generic "配置错误" and no useful console error. php artisan route:list, then curl -i 'http://localhost/ueditor?action=config' as your first debug step.
  • Path traversal via originalName. Older UEditor PHP handlers derive the saved filename from the client-supplied original name. Never trust it — generate Str::uuid() . '.' . $ext and validate the extension against the config allowlist, not mime_content_type() alone.
  • PHP limits, not package config, cap uploads. upload_max_filesize, post_max_size, and max_file_uploads in php.ini (plus nginx client_max_body_size) will reject before your max_size check runs, and UEditor reports it as a JSON parse failure rather than a size error. Align all four.
  • Asset staleness. Published UEditor JS is from Baidu's final releases; ueditor.config.js hardcodes paths like /ueditor/php/controller.php. After publishing, grep the asset directory for hardcoded paths and rewrite them to your route — otherwise the demo controller path leaks into production.
  • Version pinning is mandatory. With 0 dependents and no CI, a composer update can pull a broken tag. Pin an exact version ("ibrand/laravel-ueditor": "1.0.3"), and vendor the source into app/ if you need to patch it — you will, since upstream fixes are unlikely.
  • Fork before you depend. Score and signals here say "unmaintained integration shim," not "library." The realistic path: read the ~200 lines of controller + provider, copy them into your app as app/Http/Controllers/UEditorController.php plus a config file, and drop the dependency. You keep the one useful thing (the UEditor JSON contract) and lose the version-constraint and security-update liability.
  • Extension points to preserve if you keep the package: the config-driven disk/path, the route URI, and the controller class. Bind your own subclass via the container ($this->app->bind(UEditorController::class, MyController::class)) rather than editing vendor files, so future (however rare) updates stay mergeable.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib