Forem

David Carr for CKEditor

Posted on • Originally published at dcblog.dev on

2 1

Upload images in Ckeditor 5 with Laravel

Upload images in Ckeditor 5 with Laravel

CKeditor 5 out of the box does not come with upload capabilities. Uploading is supported with its plugins, some are official paid plugins that require subscriptions. There are a few free options.

Base64 upload adapter

This plugin allows uploads that will convert an uploaded image into base64 data. Very easy to use but will require you to save the complete base64 code with the post, this can be get long.

Docs

Simple image adapter

An image upload tool. It allows uploading images to an application running on your server using the XMLHttpRequest API with a minimal editor configuration.

Docs

Use the online builder to add the simple image adapter then download the generated bundle unzip and place the folder inside a publicly accessible place in Laravel. such as /public/js/ckeditor5

Then link ckeditor.js in the pages you want to use Ckeditor

<script src="/js/ckeditor5/build/ckeditor.js"></script>
Enter fullscreen mode Exit fullscreen mode

Using Ckeditor in a textarea.

I've made a blade component called Ckeditor so I can use:

<x-form.ckeditor wire:model="content" name="content" />
Enter fullscreen mode Exit fullscreen mode

To render the editor. I'm using Livewire and AlpineJS.

The component looks like this:

@props([
    'name' => '',
    'label' => '',
    'required' => false
])

@if ($label == '')
    @php
        //remove underscores from name
        $label = str_replace('_', ' ', $name);
        //detect subsequent letters starting with a capital
        $label = preg_split('/(?=[A-Z])/', $label);
        //display capital words with a space
        $label = implode(' ', $label);
        //uppercase first letter and lower the rest of a word
        $label = ucwords(strtolower($label));
    @endphp
@endif
<div wire:ignore class="mt-5">
    @if ($label !='none')
        <label for="{{ $name }}" class="block text-sm font-medium leading-5 text-gray-700 dark:text-gray-200">{{ $label }} @if ($required != '') <span class="text-red-600">*</span>@endif</label>
    @endif
    <textarea
        x-data
        x-init="
            ClassicEditor
                .create($refs.item, {
                simpleUpload: {
                    uploadUrl: '{{ url('admin/image-upload') }}'
                }
                })
                .then(editor => {
                    editor.model.document.on('change:data', () => {
                    @this.set('{{ $name }}', editor.getData());
                    })
               })
                .catch(error => {
                    console.error(error);
                });
        "
        x-ref="item"
        {{ $attributes }}
    >
        {{ $slot }}
    </textarea>
</div>
@error($name)
    <p class="error">{{ $message }}</p>
@enderror
Enter fullscreen mode Exit fullscreen mode

the important part is:

simpleUpload: {
    uploadUrl: '{{ url('admin/image-upload') }}'
}
Enter fullscreen mode Exit fullscreen mode

This tells Ckeditor where to upload files to.

My route is defined inside an auth group so you have to be authenticated in order to use the upload route.

Route::middleware(['web', 'auth'])->group(function () {
    //other routes
    Route::post('admin/image-upload', [UploadController::class, 'index']);
});
Enter fullscreen mode Exit fullscreen mode

Next, create an UploadController:

<?php namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
use Intervention\Image\Facades\Image;

class UploadController
{
    public function index(Request $request)
    {
        if ($request->hasFile('upload')) {

            $file = $request->file('upload');
            $name = $file->getClientOriginalName();
            $name = Str::slug($name);
            $img = Image::make($file);
            $img->stream();
            $name = str_replace('png', '', $name).'.png';

            Storage::disk('images')->put('posts/'.$name, $img);

            return response()->json([
                'url' => "/images/posts/$name"
            ]);

        }
    }
}
Enter fullscreen mode Exit fullscreen mode

First, check if there is a file request.

Next, collect the file, and define its file name.

$file = $request->file('upload');
$name = $file->getClientOriginalName();          
Enter fullscreen mode Exit fullscreen mode

I'll use a slug to rename the file name.

$name = Str::slug($name);
Enter fullscreen mode Exit fullscreen mode

Next, I use Intervention package to use its Image class to make the image and stream it.

$img = Image::make($file);
$img->stream();

Enter fullscreen mode Exit fullscreen mode

Next, remove any unwanted text from the file name

$name = str_replace('png', '', $name).'.png';
Enter fullscreen mode Exit fullscreen mode

Then save the image

Storage::disk('images')->put('posts/'.$name, $img);
Enter fullscreen mode Exit fullscreen mode

Finally, return the image path so Ckeditor can load the image into the textarea

return response()->json([
    'url' => "/images/posts/$name"
]);
Enter fullscreen mode Exit fullscreen mode

Image of Timescale

🚀 pgai Vectorizer: SQLAlchemy and LiteLLM Make Vector Search Simple

We built pgai Vectorizer to simplify embedding management for AI applications—without needing a separate database or complex infrastructure. Since launch, developers have created over 3,000 vectorizers on Timescale Cloud, with many more self-hosted.

Read more →

Top comments (1)

Collapse
 
Sloan, the sloth mascot
Comment deleted

Cloudinary image

Optimize, customize, deliver, manage and analyze your images.

Remove background in all your web images at the same time, use outpainting to expand images with matching content, remove objects via open-set object detection and fill, recolor, crop, resize... Discover these and hundreds more ways to manage your web images and videos on a scale.

Learn more

👋 Kindness is contagious

Engage with a sea of insights in this enlightening article, highly esteemed within the encouraging DEV Community. Programmers of every skill level are invited to participate and enrich our shared knowledge.

A simple "thank you" can uplift someone's spirits. Express your appreciation in the comments section!

On DEV, sharing knowledge smooths our journey and strengthens our community bonds. Found this useful? A brief thank you to the author can mean a lot.

Okay