To manage content on the website, we always need a rich text editor(WYSIWYG). The rich text content requires HTML tags that can be added only through the WYSIWYG editor. The textarea tag can’t handle content wrapped inside HTML.
There are numerous rich text editors – TinyMCE, CKEditor available on the Internet. Trix Editor is one of them. It is developed by Basecamp. The Trix editor is being used in Basecamp for managing content. This is enough to say about the reliability of this WYSIWYG editor.
The focus of this article is to show you how to install and use the Trix editor in Laravel. We will also see how to upload images in the Trix editor. Following this tutorial, you’ll be able to handle rich text content in your Laravel application.
Installation of Trix Editor
For getting started with Trix, you first need to include their JS and CSS files. Get these files from the dist directory of their official Github page. Download the trix.js
and trix.css
files.
As we need to include the above assets, create a js
and css
folder inside the public
directory of your Laravel project. Place the copied JS and CSS files in respective directories.
Uploading images on the server using Trix requires custom JavaScript code. Create the attachments.js
file and keep it under the public/js
folder. We will add code to this file in the later part of the tutorial.
Next, let’s define the Laravel routes. We have to achieve 3 tasks.
- Display Trix Editor
- Upload images in Trix Editor
- Handle content submitted via Trix Editor
The following routes will handle these tasks.
Route::get('/trix', 'TrixController@index');
Route::post('/upload', 'TrixController@upload');
Route::post('/store', 'TrixController@store');
Create a TrixController
using the Artisan command:
php artisan make:controller TrixController
The boilerplate of TrixController
would be as follows.
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class TrixController extends Controller
{
public function index()
{
return view('trix');
}
public function store(Request $request)
{
}
public function upload(Request $request)
{
}
}
Display Trix Editor
Now, create a trix.blade
file and add the following HTML to it. It will display the Trix editor.
<!DOCTYPE html>
<html lang="en">
<head>
<meta name="csrf-token" content="{{ csrf_token() }}">
<link rel="stylesheet" href="{{ asset('/css/trix.css') }}">
</head>
<body>
<form method="post" action={{ url('store') }}>
@csrf
<p>
<input id="x" type="hidden" name="content" value="" />
<trix-editor input="x" class="trix-content"></trix-editor>
</p>
<input type="submit" name="submit" value="Submit" />
</form>
<script src="{{ asset('js/trix.js') }}"></script>
<script src="{{ asset('js/attachments.js') }}"></script>
</body>
</html>
The Trix editor will be shown like the screenshot below.

We placed the Trix editor in HTML using the trix-editor
tag. The hidden field will be used to get or show content in Trix editor. This hidden field has the id
“x” which is referenced exactly in the editor’s input
attribute. When we type anything inside Trix, the content is set to the value of this hidden field. On the server side, we get the content of the Trix editor using the below code.
public function store(Request $request)
{
echo $request->input('content');
}
If you want to populate content in Trix, set the value to the hidden field as
<input id="x" type="hidden" name="content" value="<h1>This is content</h1>" />
Upload Image in Trix Editor
To add images in the Trix editor, you need to upload them on the server. Trix editor provides an event trix-attachment-add
through which we can upload the image via Ajax. We have added the upload
route for it. Let’s define a method mapped with this route.
public function upload(Request $request)
{
if($request->hasFile('file')) {
//get filename with extension
$filenamewithextension = $request->file('file')->getClientOriginalName();
//get filename without extension
$filename = pathinfo($filenamewithextension, PATHINFO_FILENAME);
//get file extension
$extension = $request->file('file')->getClientOriginalExtension();
//filename to store
$filenametostore = $filename.'_'.time().'.'.$extension;
//Upload File
$request->file('file')->storeAs('public/uploads', $filenametostore);
// you can save image path below in database
$path = asset('storage/uploads/'.$filenametostore);
echo $path;
exit;
}
}
Here, I am storing images under the public/uploads
directory. Create a symbolic link to the storage folder using the command:
php artisan storage:link
The attachments.js
file will be used to give an Ajax call on the trix-attachment-add
event. The following code will handle the Ajax request and response.
attachments.js
(function() {
var HOST = "http://localhost:8000/upload"; //pass the route
addEventListener("trix-attachment-add", function(event) {
if (event.attachment.file) {
uploadFileAttachment(event.attachment)
}
})
function uploadFileAttachment(attachment) {
uploadFile(attachment.file, setProgress, setAttributes)
function setProgress(progress) {
attachment.setUploadProgress(progress)
}
function setAttributes(attributes) {
attachment.setAttributes(attributes)
}
}
function uploadFile(file, progressCallback, successCallback) {
var formData = createFormData(file);
var xhr = new XMLHttpRequest();
xhr.open("POST", HOST, true);
xhr.setRequestHeader( 'X-CSRF-TOKEN', getMeta( 'csrf-token' ) );
xhr.upload.addEventListener("progress", function(event) {
var progress = event.loaded / event.total * 100
progressCallback(progress)
})
xhr.addEventListener("load", function(event) {
var attributes = {
url: xhr.responseText,
href: xhr.responseText + "?content-disposition=attachment"
}
successCallback(attributes)
})
xhr.send(formData)
}
function createFormData(file) {
var data = new FormData()
data.append("Content-Type", file.type)
data.append("file", file)
return data
}
function getMeta(metaName) {
const metas = document.getElementsByTagName('meta');
for (let i = 0; i < metas.length; i++) {
if (metas[i].getAttribute('name') === metaName) {
return metas[i].getAttribute('content');
}
}
return '';
}
})();
I have assigned the upload
route to the HOST
variable. Laravel requires a CSRF token for each request. I am getting this token from the meta tag added in the blade file. When you add the image in Trix, it triggers the Ajax call, uploads the image on the server, and returns the path of the uploaded image. This image then appends in the Trix editor. You can add styling to these images using the trix-content
class given to the trix-editor
tag.
.trix-content img {
width: 300px;
height: 300px;
}
I hope you understand how to install and use the Trix editor in Laravel. Check out the documentation to read more about the Trix editor.
Related Articles
- How to Install and Use CKEditor in Laravel
- How to Install and Use TinyMCE Editor in Laravel
- Resize Image in Laravel Using Intervention Image Library
If you liked this article, then please subscribe to our YouTube Channel for video tutorials.
Hallo, this has been an excelent tutorial.
I’d like to know te proper way to remove the file listening to the ” trix-attachment-remove ” event. I’m using Laravel 8.
Also, I’d like to store the path with te foreignKey related, in order to be able to authorize the access to the corresponding user.
As you might imagine, I feel confortable with Laravel and PHP, but not so much bith javascript.
Thanks anyway. Best regards. Hern’an.