Days
Hours
Minutes
Seconds
x

New Froala Editor v4.5.1 is here – Learn More

Skip to content

How to transform your LMS with a React WYSIWYG HTML editor, part 1

We’ve all been there. Huge project, impending deadlines, hopeful clients or investors, and plenty of tasking tasks left. Uploading content like rich text with images, videos, and specific formatting, for example, is not as simple as it sounds. This is especially true for LMS (learning management systems), which require course creators to upload different content in one go. To accommodate this need, we must prepare to allow as many file types as possible while also considering rich text processing and storage. Thankfully, we have WYSIWYG editors for that. In this tutorial, we’ll tackle these LMS content issues using a React WYSIWYG HTML editor.

Key takeaways

  • A WYSIWYG HTML editor significantly simplifies content processing and uploading tasks
  • Video and image uploads, processing, and transformations make LMS more engaging and powerful.
  • Froala Editor now comes with built-in Filestack integration, making image transformations and more possible within the editor.
  • You can use React, PHP (or the back-end tool of your choice), and Froala to easily get started with a modern LMS project.
  • As your mastery with WYSIWYG editors and file upload tools grows, so do the capabilities of your LMS.

Defining the scope and features of our LMS project

First, let me clarify that this isn’t a full tutorial for creating a full-fledged LMS. Instead, this is a guide for those who want to have robust content editing and uploading features within their projects. We will be building the front end of the application using React and Froala. For file uploading, we’ll leverage the newly integrated Filestack within the editor. Finally, we will use PHP for the back-end parts and SQL Server for storing and retrieving the data.

Our mini LMS will have the following features:

  • View and add courses – each course will have a title, description, date published, and a unique ID.
  • View and add chapters – each course will consist of chapters, which contain a title, description, content, date published, and a unique ID.

We’ll first set up the React application and Froala Editor. And then, we will create the front end of the application, followed by the back end and database tables. In the end, we’ll run a demo of the application.

Setting up the React project and the WYSIWYG HTML editor

Let’s start our project by creating our React app and installing the packages that we need:  

npx create-react-app demo-lms
cd demo-lms
npm install react-froala-wysiwyg --save

npm install react-router-dom

 

Now, you should have a React application with the Froala WYSIWYG HTML editor and page routing dependencies. The next thing we need to do is create a new folder under “src” called “components.” Afterwards, create a new file named “FroalaComponent.jsx” and insert the following:

import React, { useEffect } from 'react';
import 'froala-editor/css/froala_style.min.css';
import 'froala-editor/css/froala_editor.pkgd.min.css';
import FroalaEditorComponent from 'react-froala-wysiwyg';
import 'froala-editor/js/plugins.pkgd.min.js';

function FroalaComponent({ setChapterContent, setChapterImage }) {
  const config = {
    filestackOptions: {
      uploadToFilestackOnly: true,
      filestackAPI: 'InsertYourFilestackAPIHere',
    },
    events: {
      'contentChanged': function () {
        setChapterContent(this.html.get());
      },
      'filestack.uploadedToFilestack': function (response) {
        if(response && response.filesUploaded[0].url){
          setChapterImage(response.filesUploaded[0].url);
        }

        else{
          console.error("Image upload failed, no URL found in response", response);
        }
      }
},
  };

  useEffect(() => {
    const filestackScript1 = document.createElement('script');
        filestackScript1.src = 'https://static.filestackapi.com/filestack-js/3.32.0/filestack.min.js';
        filestackScript1.async = true;
        document.body.appendChild(filestackScript1);

        const filestackScript2 = document.createElement('script');
        filestackScript2.src = 'https://static.filestackapi.com/filestack-drag-and-drop-js/1.1.1/filestack-drag-and-drop.min.js';
        filestackScript2.async = true;
        document.body.appendChild(filestackScript2);

        const filestackScript3 = document.createElement('script');
        filestackScript3.src = 'https://static.filestackapi.com/transforms-ui/2.x.x/transforms.umd.min.js';
        filestackScript3.async = true;
        document.body.appendChild(filestackScript3);

        const filestackStylesheet = document.createElement('link');
        filestackStylesheet.rel = 'stylesheet';
        filestackStylesheet.href = 'https://static.filestackapi.com/transforms-ui/2.x.x/transforms.css';
        document.head.appendChild(filestackStylesheet);

    return () => {
      document.body.removeChild(filestackScript1);
      document.body.removeChild(filestackScript2);
      document.body.removeChild(filestackScript3);
      document.head.removeChild(filestackStylesheet);
    };
  }, []);

  return (
    <div className="editor">
      <FroalaEditorComponent tag='textarea' config={config} />
    </div>
  );
}

export default FroalaComponent;

The first thing we need to do is declare our component and its properties. Note that for the Froala config, we have to declare the Filestack options, including our Filestack API. You can get one by creating a free Filestack account or starting a free trial of a paid plan. Also note that we’re handling Froala’s content-change events and Filestack’s image upload event. This is for storing a course chapter’s content and image URL later.

Additionally, we’re loading Filestack-related scripts and styles dynamically using useEffect. That way, we can easily use Filestack’s drag-and-drop functionality, image uploads, and other features. Lastly, we load our FroalaEditorComponent and its configuration. If you need additional guidance on setting up Froala for React, follow this helpful article.

Creating the LMS

Now that we have the application and our Froala WYSIWYG HTML editor component ready, let’s build our LMS! Start by creating 4 files under the components folder:

  • Courses.jsx: For viewing courses and navigating to a course’s chapters
import React, { useState, useEffect } from 'react';
import CourseModal from './CourseModal';
import { Link } from 'react-router-dom';

function Courses() {
  const [courses, setCourses] = useState([]);
  const [isModalOpen, setIsModalOpen] = useState(false);

  const fetchCourses = async () => {
    // Fetch courses from the back end
    const response = await fetch('path-to-backend/demo-lms-backend/fetchCourses.php');
    const data = await response.json();
    setCourses(data);
  };

  useEffect(() => {
    fetchCourses();
  }, []);

  const handleSaveCourse = () => {
    fetchCourses(); // Fetch courses again after saving a new one
    setIsModalOpen(false);
  };

  return (
    <div className="course-list">
      <h1>My Simple yet Powerful LMS</h1>
      <h2>Courses</h2>

      <button onClick={() => setIsModalOpen(!isModalOpen)}>
        {isModalOpen ? 'Close' : 'Add a Course'}
      </button>

      {isModalOpen && <CourseModal onSaveCourse={handleSaveCourse} onClose={() => setIsModalOpen(false)} />}
      {courses.map((course) => (
        <div key={course.course_id} className="course-card">
          <h3>{course.course_title}</h3>
          <p>{course.course_description}</p>
          <p>Date Published: {course.date_published ? new Date(course.date_published.date).toLocaleDateString() : 'N/A'}</p>
          <Link to={`/chapters/${course.course_id}`}>
            <button>View Course</button>
          </Link>
        </div>
      ))}
    </div>
  );
}

export default Courses;
  • CourseModal.jsx: For saving courses
import React, { useState } from 'react';

function CourseModal({ onSaveCourse, onClose }) {
  const [courseTitle, setCourseTitle] = useState('');
  const [courseDescription, setCourseDescription] = useState('');

  const handleSubmitCourse = async (e) => {
    e.preventDefault();

    const newCourse = {
      title: courseTitle,
      description: courseDescription,
      date_published: new Date().toISOString().split('T')[0],
    };

    const response = await fetch('path-to-backend/demo-lms-backend/saveCourse.php', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify(newCourse),
    });

    const result = await response.json();
    if (response.ok) {

      // This will call fetchCourses from Courses.jsx
      onSaveCourse();
    } else {
      console.error('Failed to save course:', result);
    }
  };

  return (
    <div className="modal">
      <form onSubmit={handleSubmitCourse}>
        <h3>New Course</h3>
        <label>Title</label>
        <input type="text" value={courseTitle} onChange={(e) => setCourseTitle(e.target.value)} required />
     
        <label>Description</label>
        <textarea value={courseDescription} onChange={(e) => setCourseDescription(e.target.value)} required />

        <button type="submit">Save</button>
        <button type="button" onClick={onClose}>Cancel</button>
      </form>
    </div>
  );
}

export default CourseModal;
  • Chapters.jsx: For viewing the chapters of a course and navigating back to the courses
import React, { useState, useEffect } from 'react';
import { useParams } from 'react-router-dom';
import ChapterModal from './ChapterModal';
import { Link } from 'react-router-dom';

function Chapters() {
  const { courseId } = useParams();
  const [chapters, setChapters] = useState([]);
  const [course, setCourse] = useState(null); // To store course details
  const [isModalOpen, setIsModalOpen] = useState(false);

  // Fetch chapters for the course
  const fetchChapters = async () => {
    const response = await fetch(`path-to-backend/demo-lms-backend/fetchChapters.php?course_id=${courseId}`);
    const data = await response.json();
    setChapters(data);
  };

  // Fetch course details
  const fetchCourseDetails = async () => {
    const response = await fetch(`path-to-backend/demo-lms-backend/getCourseById.php?courseId=${courseId}`);
    const data = await response.json();
    setCourse(data);
  };

  useEffect(() => {
    fetchChapters();
    fetchCourseDetails(); // Fetch course details on load
  }, [courseId]);

  const handleSaveChapter = (newChapter) => {
    setChapters([...chapters, newChapter]);
    setIsModalOpen(false);
  };

  if (!course) {
    return <p>Loading course details...</p>;
  }

  return (
    <div className="course-details">
      <h1>{course.course_title}</h1>
      <p>Description: {course.course_description}</p>
      <p>Date Published: {course.date_published ? new Date(course.date_published.date).toLocaleDateString() : 'N/A'}</p>
      <Link to={`/`}>
        <button>Back to Courses</button>
      </Link>

      <button onClick={() => setIsModalOpen(!isModalOpen)}>
        {isModalOpen ? 'Close' : 'Add a Chapter'}
      </button>
   
      <div className="chapter-list">
        {chapters.map((chapter) => (
          <div key={chapter.chapter_id} className="chapter-card">
            <h3>{chapter.chapter_title}</h3>
            <p>{chapter.chapter_description}</p>
            <p>Date Published: {chapter.date_published}</p>
          </div>
        ))}
      </div>

      {isModalOpen && <ChapterModal courseId={courseId} onSaveChapter={handleSaveChapter} onClose={() => setIsModalOpen(false)} />}
    </div>
  );
}

export default Chapters;
  • ChapterModal.jsx: For saving chapters within a course
import React, { useState } from 'react';
import FroalaComponent from './FroalaComponent';

function ChapterModal({ courseId, onSaveChapter, onClose }) {
  const [chapterTitle, setChapterTitle] = useState('');
  const [chapterDescription, setChapterDescription] = useState('');
  const [chapterContent, setChapterContent] = useState('');
  const [chapterImage, setChapterImage] = useState('');

  const handleSubmitChapter = async (e) => {
    e.preventDefault();

    console.log('Chapter Image URL:', chapterImage);

    const newChapter = {
      course_id: courseId,
      title: chapterTitle,
      description: chapterDescription,
      content: chapterContent,
      chapter_img: chapterImage, // for Filestack URL
      date_published: new Date().toISOString().split('T')[0],
    };

    const response = await fetch('path-to-backend/demo-lms-backend/saveChapter.php', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify(newChapter),
    });

    const result = await response.json();
    if (response.ok) {
      onSaveChapter(result);
    } else {
      console.error('Failed to save chapter:', result);
    }
  };

  return (
    <div className="modal">
      <form onSubmit={handleSubmitChapter}>
        <h3>Add New Chapter</h3>
        <label>Title</label>
        <input type="text" value={chapterTitle} onChange={(e) => setChapterTitle(e.target.value)} required />
     
        <label>Description</label>
        <textarea value={chapterDescription} onChange={(e) => setChapterDescription(e.target.value)} required />
     
        <label>Content</label>
        <FroalaComponent setChapterContent={setChapterContent} setChapterImage={setChapterImage} />

        <div><button type="submit">Save</button> <button type="button" onClick={onClose}>Cancel</button></div>
      </form>
    </div>
  );
}

export default ChapterModal;

Lastly, replace the default code in your App.js with:

import React, { useState } from 'react';
import { BrowserRouter as Router, Route, Routes } from 'react-router-dom';
import './App.css';
import Courses from './components/Courses';
import Chapters from './components/Chapters';

function App() {
  return (
    <Router>
      <Routes>
        <Route path="/" element={<Courses />} />
        <Route path="/chapters/:courseId" element={<Chapters />} />
      </Routes>
    </Router>
  );
}

export default App;

Here’s a quick summary of how our components work:

  • App.js displays the Courses page first. Using the fetchCourses function, the application will send a fetch request to fetchCourses.php on the server. This loads all courses from the database table.
  • When the user clicks the “Add a Course” button, we’ll show the CourseModal component. The user can then save a course through a fetch request to saveCourse.php. After saving the course, the application refreshes the courses.
  • The Chapters and ChapterModal components work similarly, except that loading and saving chapter data requires a course ID. Furthermore, we add the Froala component in our ChapterModal.

After creating the front end of our LMS, we’ll handle the back end of the application next.

Setting up the DB tables and back-end codes

For our database tables, we’ll create two simple tables in SQL Server:

  • course
    • course_id char(10)
    • course_title varchar(100)
    • course_description varchar(255)
    • date_published date
  • chapter
    • course_id char(10)
    • chapter_id char(10)
    • chapter_title varchar(100)
    • chapter_description varchar(255)
    • chapter_content varchar(max)
    • chapter_img_url varchar(255)
    • date_published date

These are just some basic tables, so you will want to improve this or plan ahead when implementing your LMS. Note that we plan to store the contents of the editor in chapter_content. On the other hand, we’ll store the Filestack URL in the chapter_img_url column. For now, we choose 255 as the max length, but you might want to adjust this in your implementation.

Alright, we’re almost done! The last thing we need to do is create our PHP files for fetching and saving data. We also assume that we have a “connection.php” that connects to a database instance. Here are our PHP files and their respective purposes:

  • fetchCourses.php: Retrieve all course data from the course table
<?php
    include "connection.php";

    $query = "SELECT course_id, course_title, course_description, date_published FROM course";
    $result = sqlsrv_query($conn, $query);

    $courses = array();
    while ($row = sqlsrv_fetch_array($result, SQLSRV_FETCH_ASSOC)) {
        $courses[] = $row;
    }

    sqlsrv_close($conn);
    echo json_encode($courses);
?>
  • saveCourse.php: Generate a unique course ID and save the course data
<?php
    include "connection.php";

    $input = json_decode(file_get_contents("php://input"), true);

    $course_title = $input["title"];
    $course_description = $input["description"];

    $query = "
        DECLARE @course_id CHAR(10)

        WHILE 1 = 1
        BEGIN
            SET @course_id = LEFT(CONVERT(NVARCHAR(36), NEWID()), 10)

            IF NOT EXISTS (SELECT 1 FROM course WHERE course_id = @course_id)
            BEGIN
                BREAK
            END
        END

        INSERT INTO course
        (course_id, course_title, course_description, date_published)
        VALUES
        (@course_id, ?, ?, GETDATE())
    ";
    $params = array($course_title, $course_description);
    $result = sqlsrv_query($conn, $query, $params);

    if($result===false) {
        echo json_encode(["error" => "Failed to save course"]);
    }
    else{
        echo 1;
    }
    sqlsrv_close($conn);
?>
  • getCourseById.php: Select all information of a specific course (for generating course data in our Chapters component)
<?php
    include "connection.php";

    if (isset($_GET["courseId"])) {
        $courseId = $_GET["courseId"];

        $query = "SELECT course_id, course_title, course_description, date_published FROM course WHERE course_id = ?";
        $params = array($courseId);
        $stmt = sqlsrv_query($conn, $query, $params);

        if($stmt === false){
            http_response_code(500);
            echo json_encode(["error" => "Failed to query the database."]);
            exit;
        }

        $course = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC);

        if($course){
            echo json_encode($course);
        }
        else{
            http_response_code(404);
            echo json_encode(["message" => "Course not found"]);
        }

        sqlsrv_free_stmt($stmt);
        sqlsrv_close($conn);
    }
    else{
        echo json_encode(["message" => "Course ID not provided"]);
    }
?>
  • fetchChapters.php: Get all chapters in a course
<?php
    include "connection.php";

    $course_id = $_GET["course_id"];

    $query = "SELECT chapter_title, chapter_description, date_published FROM chapter WHERE course_id = ?";
    $params = array($course_id);
    $result = sqlsrv_query($conn, $query, $params);

    if ($result === false) {
        die("Error in query preparation/execution: " . print_r(sqlsrv_errors(), true));
    }
    $chapters = array();
    while($row = sqlsrv_fetch_array($result, SQLSRV_FETCH_ASSOC)){
        $chapters[] = $row;
    }

    sqlsrv_close($conn);
    echo json_encode($chapters);
?>
  • saveChapter.php: Add a chapter to a course
<?php
    include "connection.php";

    $input = json_decode(file_get_contents("php://input"), true);

    $course_id = $input["course_id"];
    $chapter_title = $input["title"];
    $chapter_description = $input["description"];
    $chapter_content = $input["content"];
    $chapter_img_url = $input["chapter_img"];

    $query = "
        DECLARE @chapter_id CHAR(10)

        WHILE 1 = 1
        BEGIN
            SET @chapter_id = LEFT(CONVERT(NVARCHAR(36), NEWID()), 10)

            IF NOT EXISTS (SELECT 1 FROM chapter WHERE chapter_id = @chapter_id)
            BEGIN
                BREAK
            END
        END

        INSERT INTO chapter
        (course_id, chapter_id, chapter_title, chapter_description, chapter_content, chapter_img_url, date_published)
        VALUES
        (?, @chapter_id, ?, ?, ?, ?, GETDATE())
    ";

    $params = array($course_id, $chapter_title, $chapter_description, $chapter_content, $chapter_img_url);
    $result = sqlsrv_query($conn, $query, $params);

    if($result===false){
        echo json_encode(["error" => "Failed to save chapter"]);
    }
    else{
        echo 1;
    }
    sqlsrv_close($conn);
?>

And that’s it! Now, we have all we need for our React LMS with image transformations and rich-text editing. 

Seeing the React WYSIWYG HTML editor LMS in action

Let’s end this tutorial by checking how our React LMS works. After running npm start, we’ll see the homepage, which is empty at first. So, let’s add a course:

A GIF showing the sample LMS' feature that allows users to create courses.

We now have a course. Note that for demo purposes, we didn’t apply that much CSS for now, which is why the input fields and other elements look out of place. Next, let’s view the course and try to add a chapter. After clicking “Add a Chapter,” we will see the WYSIWYG HTML editor along with two input fields.

A GIF showing how you can create an LMS chapter for a course using Froala, Filestack, and React.

Once we’ve selected, cropped, and uploaded the image through the integrated Filestack file picker, we’ll now apply some transformations to the image.

A GIF showing how you can transform images using Froala's built-in Filestack file picker.

Lack of CSS aside, this LMS already looks and feels like a top-notch editing and content processing tool because of the WYSIWYG editor. Lastly, we save the enhanced image, insert a document (a sample chapter outline), add the chapter title and description, and save the chapter.

A GIF that shows how you can upload documents using Froala and Filestack.

Now, let’s check the database to see if we saved the information correctly. Note that I added the chapter to the course about 4 days after creating the course.

Database results that show correctness in terms of data uploaded

Let’s also check our Filestack dashboard:

We can see that we have both the edited image and our demo PDF in our Filestack dashboard. If we now download the image file, we’ll see the image that we transformed earlier in our LMS!

An image that was uploaded using Froala Editor and cropped and edited using Filestack

And there you have it: a React WYSIWYG HTML editor-powered LMS. Undoubtedly, this is far from a finished or even decent LMS product. However, it’s a good start, especially if you plan on implementing comprehensive image handling and content editing on your application. Moreover, we can still do a lot more that I haven’t shown you yet. Next time, we’ll continue this mini project and load the image from Filestack back to our application. Happy coding!

Get your Filestack API here for free.

Integrating Google Cloud Storage in Vue.js Rich Text Editor with Froala

Froala Vue.js rich text editor

As businesses continue to embrace the power of cloud computing, the need to effortlessly manage and store files has become paramount. If you’re a Vue.js developer working with the Froala rich-text editor, you may have encountered the challenge of implementing a file-uploading process that seamlessly integrates with Google Cloud Storage.

Fortunately, the latest version of Froala, V4.3, has introduced a game-changing solution: the Filestack plugin. This innovative feature makes integrating your Vue.js WYSIWYG editor with Google Cloud Storage a breeze, requiring only a few lines of code to set up.

In this article, we’ll dive deep into how Froala V4.3 has simplified this process, empowering you to effortlessly store your files in the Google Cloud while providing your users with a seamless rich-text editing experience. We will discover practical insights and step-by-step guidance to help you master this powerful integration.

So, let’s explore how you can elevate your Vue.js projects by seamlessly connecting your Froala rich-text editor with the reliability and scalability of Google Cloud Storage.

Wysiwyg editor with Google cloud integration

How does Froala V4.3 simplify the integration with Google Cloud?

Froala V4.3 introduces a game-changing feature that streamlines the process of integrating your Vue.js rich-text editor with Google Cloud Storage. This new capability comes in the form of the Filestack plugin, which seamlessly integrates the Filestack Picker directly into the Froala editor.

With the Filestack plugin, users can now upload images, videos, and files directly from the rich-text editor, and these assets will be automatically stored in your Google Cloud Storage. This is made possible by the Filestack platform, which supports a wide range of popular cloud storage services, including Google Cloud.

The integration process is incredibly straightforward. All you need to do is connect your Google Cloud account to your Filestack dashboard, and you’re good to go. From that point on, any files uploaded through the Filestack Picker within the Froala editor will be directly saved to your Google Cloud Storage, without the need for any additional configuration or complex integrations.

This streamlined approach not only saves you time and effort but also ensures a seamless user experience for your content creators. They can focus on crafting their content, while the Froala-Filestack-Google Cloud integration handles the behind-the-scenes file management, allowing you to leverage the power and reliability of Google Cloud Storage with minimal hassle.

Let’s explore how this integration works.

Step 1: Create a simple Vue project

Skip this step if you will install the editor in an existing Vue app.

Run the following commands to create a new Vue 3 project.

npm install -g @vue/cli

vue create my-froala-vue-app

cd my-froala-vue-app

The above code creates a new Vue 3 project named “my-froala-vue-app” and navigates to the project directory. This provides a clean starting point for integrating the Froala rich-text editor and enabling the Google Cloud Storage integration using the Filestack plugin.

Step 2: Install the Froala Editor Vue SDK

Next, you’ll need to install the Froala Editor for Vue.js. Run the following commands in your project directory:

npm install vue-froala-wysiwyg --save

This will add the required dependencies to your project, allowing you to use the Froala editor within your Vue application.

Step 3: Include Froala in Your Application

3.1 Import Froala Editor in main.js

In your “main.js” file, import the Froala associated CSS and JS files:

import { createApp } from 'vue'
import App from './App.vue'

//Import Froala Editor plugins
import 'froala-editor/js/plugins.pkgd.min.js';


// Import Froala Editor css files.
import 'froala-editor/css/froala_editor.pkgd.min.css';
import 'froala-editor/css/froala_style.min.css';


// Import Froala Editor component
import VueFroala from 'vue-froala-wysiwyg';

const app = createApp(App);          

app.use(VueFroala);
app.mount('#app');

This step ensures that the Froala Editor is available throughout your Vue.js application, allowing you to use it in your components.

3.2 Use Froala in a Vue Component

In your “App.vue” file, add the Froala component within the template and add some initial configuration.

<template>

  <froala id="edit" :tag="'textarea'" :config="config" v-model:value="model"></froala>

</template>


<script>

export default {

  name: 'App',

  data () {

    return {

      config: {

        heightMin: 300,

      },

      model: '<i>Edit Your Content Here!</i>'

    }

  }

}

</script>


<style>

#app {

  font-family: Avenir, Helvetica, Arial, sans-serif;

  -webkit-font-smoothing: antialiased;

  -moz-osx-font-smoothing: grayscale;

  text-align: center;

  color: #2c3e50;

  margin-top: 60px;

}

</style>

The Froala component has three attributes:

  • :tag attribute is used to tell on which tag the editor is initialized.
  • :config attribute is used to configure the editor options.
  • v-model:value Used to load editor content. This value is affected by editor HTML changes.

Step 4: Include Filestack for Uploading and Storing Files

Since we already included the “plugins.pkgd.min.js” file in our application, then the Froala Filestack is already included and active by default. However, to correctly display the Filestack File Picker and UI Transformation tools in the editor, include the following Filestack stylesheet and scripts:

Open the “public/index.html” file and include the mentioned scripts.

<!DOCTYPE html>
<html lang="">

<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width,initial-scale=1.0">
  <link rel="icon" href="<%= BASE_URL %>favicon.ico">
  <title>
    <%= htmlWebpackPlugin.options.title %>
  </title>
  <link rel="stylesheet" href="https://static.filestackapi.com/transforms-ui/2.x.x/transforms.css" />

</head>

<body>
  <noscript>
    <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled.
        Please enable it to continue.</strong>
  </noscript>
  <div id="app"></div>
  <!-- built files will be auto injected -->
  <script src="https://static.filestackapi.com/filestack-js/3.32.0/filestack.min.js"></script>
  <script
    src="https://static.filestackapi.com/filestack-drag-and-drop-js/1.1.1/filestack-drag-and-drop.min.js"></script>
  <script src="https://static.filestackapi.com/transforms-ui/2.x.x/transforms.umd.min.js"></script>
</body>

</html>

Step 5: Create a Filestack Account

To integrate the Filestack File Picker with your Froala Editor, you’ll need to create a Filestack account and obtain an API key.

  1. Sign up for a Filestack Account:
    You can create a free Filestack account with low bandwidth, uploads, transformations, and storage limits. However, to upload files to Google Cloud you need a paid plan. Start a free trial of a paid plan based on your needs.
  2. Obtain the Filestack API Key:
    • After creating your account, you’ll be taken to the Filestack dashboard.
    • In the dashboard, locate the “API Keys” section and copy your “API Key”.
    • You’ll need this API key to configure the Filestack integration with your Froala Editor.

Get Filestack API key

With your Filestack account and API key, you’re now ready to integrate the Filestack File Picker into your Froala Editor, allowing your users to upload, store, and transform files directly within the rich-text editing experience.

Step 6: Filestack Configuration

To complete the Filestack integration, we need to configure the following options and events:

  • Set the filestackOptions.filestackAPI to your Filestack API key.
  • (Optional) Set the filestackOptions.uploadToFilestackOnly to true. This will handle all file uploads by Filestack.
  • (Optional) Pass the File Picker configurations in the filestackOptions.pickerOptions option to customize the Filestack Picker.
  • (Optional) Configure the filestack.filestackPickerOpened event. This allows you to execute a custom action after a user opens the Filestack File Picker.
  • (Optional) Configure the filestack.filestackPickerClosed event. This allows you to execute a custom action after a user closes the Filestack File Picker.
  • (Optional) Configure the filestack.uploadedToFilestack event. This allows you to execute a custom action when files are successfully uploaded to your cloud storage.
  • (Optional) Configure the filestack.uploadFailedToFilestack event. This allows you to execute a custom action if the file upload fails.

Open your “App.vue” file and modify the data() function:

      data () {
      
        return {
        
          config: {
            
            heightMin: 300,
            filestackOptions: {
              uploadToFilestackOnly: true,
              filestackAPI: "***",
            },

            events: {
              'filestack.uploadedToFilestack': function () {
                  console.log("Callback is triggered for uploaded to filestack ",)
              },

              'filestack.filestackPickerOpened': function () {
                  console.log("Callback is triggered for picker opened ",)
              },

              'filestack.filestackPickerClosed': function () {
                  console.log("Callback is triggered for picker closed ",)
              },

              'filestack.uploadFailedToFilestack': function () {
                  console.log("Callback is triggered for file stack failed ",)
              },

            },
          },
        
          model: '<i>Edit Your Content Here!</i>'
        
        }
      
      }

Step 7: Google Cloud Configuration

Log in to your Filestack Dev Portal to configure your storage options so that uploaded files are saved in your Google Cloud account instead of Filestack’s default S3 bucket.

Simply add your service account key and ensure it has the Storage Object Admin role.

Note that depending on your internal GCS settings, additional permissions may be required, such as Storage Admin, Storage Object Creator, and Storage Object Viewer.

Obtain the JSON key for this account and paste it into the Access Key field in the GCS section of the developer portal.

Step 8: Start Your Application

With the Filestack integration and Google Cloud Storage configuration complete, you can now start your application. Run the following command in your terminal:

npm run serve

This command will start the development server and run your application at “http://localhost:8080”.

Froala Filestack integration

When a user clicks the Filestack File Picker button, the picker will open, allowing them to select files from various sources. The selected files will be automatically uploaded to your Google Cloud Storage account, and you can handle the successful or failed upload events using the configured callbacks. This integration provides a seamless file management experience within your Froala Editor-powered application.

What other cloud storage services are supported?

In addition to Google Cloud Storage, Filestack supports integration with other popular cloud storage services such as Amazon S3, Rackspace, Microsoft Azure Blob Storage, and Dropbox. You can configure the desired cloud storage provider in the Filestack Developer Portal and use the same integration approach as outlined for Google Cloud Storage. This flexibility allows you to choose the cloud storage solution that best fits your application’s requirements and infrastructure. The Filestack File Picker seamlessly handles file uploads and transformations, regardless of the underlying cloud storage provider.

Unlock the Power of Seamless Cloud Integration with Froala, Filestack, and Google Cloud Storage

By leveraging the Filestack plugin in Froala V4.3, you can now effortlessly integrate your Vue.js rich-text editor with the reliability and scalability of Google Cloud Storage. This game-changing integration empowers your content creators to focus on crafting exceptional content, while the behind-the-scenes file management is handled seamlessly.

With just a few lines of code, you can set up this powerful integration and unlock a new level of productivity and efficiency in your Vue.js projects. Say goodbye to the hassle of complex file upload processes and hello to a streamlined, user-friendly experience that delights your users.

Get your Filestack API here for free.

Managing Linux WYSIWYG HTML Editors with Destroy/Init API

Let’s explore how to make linux WYSIWYG editors work better for your users on Linux. With Froala’s destroy/init API, you can create a smoother experience while managing system resources well.

Key Takeaways

  • Save memory by controlling when editors load
  • Help users work with many documents at once
  • Speed up page loading times
  • Keep browsers running smoothly
  • Make editing work well on all Linux browsers

Getting Started on Ubuntu

First, let’s set up the basics with Angular:

# Create new Angular project
sudo npm install -g @angular/cli
ng new wysiwyg-editor --no-standalone
cd wysiwyg-editor

# Install Froala dependencies
npm install angular-froala-wysiwyg --save
npm install font-awesome --save  # Optional for icons

Making Editors Work Smarter

Here’s how to use the destroy/init API:

// editor.component.ts
import { Component } from '@angular/core';

@Component({
  selector: 'app-editor',
  template: `
    <div [froalaEditor]="options" (froalaInit)="initialize($event)">
      <p>Edit your content here</p>
    </div>
    <button (click)="destroyEditor()">Close Editor</button>
    <button (click)="initEditor()">Open Editor</button>
  `
})
export class EditorComponent {
  private initControls: any;

  options = {
    placeholderText: 'Start typing...',
    events: {
      initialized: function() {
        console.log('Editor initialized');
      }
    }
  }

  initialize(initControls: any) {
    this.initControls = initControls;
  }

  destroyEditor() {
    if (this.initControls) {
      this.initControls.destroy();
    }
  }

  initEditor() {
    if (this.initControls) {
      this.initControls.initialize();
    }
  }
}

Why This Helps Your Users

First, users can switch between documents quickly because the editor isn’t slowing things down. Moreover, when someone opens a new document, it loads right away since we’re not loading everything at once.

Additionally, users can work on several documents without their browser getting sluggish. This is especially helpful on Linux systems where people often have many programs running at once.

Also, when users first load your app, it starts up faster because we only load editors when needed. As a result, users can get to work sooner.

Where This Works Best

Content Management

If your users work with blog posts or articles, they’ll notice how smoothly they can switch between different pieces. Therefore, their work flows better without waiting for editors to load.

Documentation Work

When writing documentation, users often jump between different sections. Subsequently, they can edit various parts without the system slowing down.

Teaching Platforms

For teachers creating course content, they can easily move between lessons. Thus, they spend less time waiting and more time creating.

Testing on Different Browsers

To make sure everything works for Linux users, test on various browsers:

# Install browsers (Ubuntu/Debian)
sudo apt update
sudo apt install firefox chromium-browser

Real Example

Here’s how to set up an editor for document management:

import { Component } from '@angular/core';

@Component({
  selector: 'app-editor',
  template: `
    <div [froalaEditor]="options" 
         (froalaInit)="initialize($event)"
         [(froalaModel)]="content">
    </div>
  `
})
export class EditorComponent {
  private initControls: any;

  options = {
    heightMin: 200,
    placeholderText: 'Start typing...',
    toolbarButtons: {
      moreText: {
        buttons: ['bold', 'italic', 'underline']
      },
      moreParagraph: {
        buttons: ['alignLeft', 'alignCenter']
      },
      moreRich: {
        buttons: ['insertLink', 'insertImage']
      }
    }
  }
}

Tips for Better Performance

Remember these key points:

  1. Close editors when users leave a page
  2. Open editors only when users need them
  3. Save user work before closing editors

Browser Support

The destroy/init API works well on all major Linux browsers(check out Froala Browser Support):

  • Firefox
  • Chrome
  • Opera

In conclusion, using the destroy/init API makes editing smoother for your users. As a result, they can focus on creating content instead of waiting for editors to load. Furthermore, your app stays responsive even when users work with multiple documents.

Most importantly, this approach helps you build better editing tools that work well on any Linux system. Finally, your users get a consistent experience no matter which browser they choose.

React Rich-Text Editor with Advanced Images and Cloud Storage

React rich-text editor

Rich-text editor is a crucial component that allows your users to seamlessly add and edit content. But have you ever found the process of integrating image uploads and storage to be a complex and time-consuming task?

Rich-text editors are undoubtedly popular, but the ability to easily insert and display images is often a pain point. Traditionally, developers have had to write additional code to handle the uploading and storage of images, a process that can be both tedious and error-prone.

However, thanks to the integration between Froala and Filestack, introduced in Froala version 4.3, the uploading and storing of any type of files has become a straightforward process. In this article, we’ll guide you through the setup of this powerful integration within your React applications, empowering you to create a React rich-text editor with advanced image editing capabilities and a seamless cloud storage solution.

Get ready to streamline your content management workflow and provide your users with a truly exceptional experience. Let’s dive in and explore how you can leverage this powerful combination to take your web applications to new heights.

A React Rich-Text Editor with Advanced Image Capabilities and Seamless Cloud Storage Solution

Step 1: Creating A React App.

Skip this step if you will install the editor in an existing React app.

Run the following commands to create a new React application

npm install -g create-react-app

npx create-react-app froala-app

cd froala-app

The above code creates a new React application named “froala-app” and navigates to the project directory. This sets up the necessary files and folders for a basic React application, which you can then customize to integrate the Froala Rich Text Editor and Filestack for file management.

Step 2: Install Froala React Component

Next, you’ll need to install the Froala Rich Text Editor SDK for React. Run the following commands in your project directory:

npm install react-froala-wysiwyg --save

This will add the required dependencies to your project, allowing you to use the Froala editor within your React application.

Step 3: Include Froala in Your Application

To create a Froala editor component with your custom configuration, create a new file “src/components/FroalaComponent.jsx” and add the following code

import React from 'react';

// Require Editor CSS files.

import 'froala-editor/css/froala_style.min.css';

import 'froala-editor/css/froala_editor.pkgd.min.css';

import FroalaEditorComponent from 'react-froala-wysiwyg';

import 'froala-editor/js/plugins.pkgd.min.js';

// Render Froala Editor component.
function FroalaComponent (){

  return (
  
    <div class="editor">
    
    <h3> Froala's React WYSIWYG Editor</h3>
    
    <FroalaEditorComponent tag='textarea'/>
    
    </div>
  
  );

}

export default FroalaComponent;

In the above code, we did the following

  • Import the necessary Froala CSS files and the FroalaEditorComponent from the “react-froala-wysiwyg” library.
  • Import the /plugins.pkgd.min.js to load the full-featured editor with all default plugins loaded.
  • Create a functional component called FroalaComponent that renders the Froala editor within a div.
  • Set the tag attribute of FroalaEditorComponent to textarea, this means the editor will be initialized at textarea HTML element.
  • (Optional) Set the config attribute of FroalaEditorComponent and pass your custom Froala options values through it. We will use it later to set up Filestack plugin options and events.

Step 4: Include Filestack For Uploading and Storing Files

To correctly display the Filestack File Picker and UI Transformation tools in the editor, include the following Filestack files:

We can directly add the script and link tags to your React project’s “public/index.html” file. This method ensures that the scripts are loaded with the initial HTML file.

However, for better performance, we will use the useEffect hook to dynamically add the scripts and stylesheet to the document when the component mounts and remove them when the component unmounts. This ensures the external resources are properly loaded and unloaded with the component lifecycle.

Here’s the “FroalaComponent.jsx” after including the Filestack scripts and stylesheet:

import React, { useEffect } from 'react';
import 'froala-editor/css/froala_style.min.css';
import 'froala-editor/css/froala_editor.pkgd.min.css';
import FroalaEditorComponent from 'react-froala-wysiwyg';
import 'froala-editor/js/plugins.pkgd.min.js';

function FroalaComponent() {

    useEffect(() => {
        const filestackScript1 = document.createElement('script');
        filestackScript1.src = 'https://static.filestackapi.com/filestack-js/3.32.0/filestack.min.js';
        filestackScript1.async = true;
        document.body.appendChild(filestackScript1);

        const filestackScript2 = document.createElement('script');
        filestackScript2.src = 'https://static.filestackapi.com/filestack-drag-and-drop-js/1.1.1/filestack-drag-and-drop.min.js';
        filestackScript2.async = true;
        document.body.appendChild(filestackScript2);

        const filestackScript3 = document.createElement('script');
        filestackScript3.src = 'https://static.filestackapi.com/transforms-ui/2.x.x/transforms.umd.min.js';
        filestackScript3.async = true;
        document.body.appendChild(filestackScript3);

        const filestackStylesheet = document.createElement('link');
        filestackStylesheet.rel = 'stylesheet';
        filestackStylesheet.href = 'https://static.filestackapi.com/transforms-ui/2.x.x/transforms.css';
        document.head.appendChild(filestackStylesheet);

        return () => {
            document.body.removeChild(filestackScript1);
            document.body.removeChild(filestackScript2);
            document.body.removeChild(filestackScript3);
            document.head.removeChild(filestackStylesheet);
        };
    }, []);

    return (
        <div className="editor">
            <h3>Froala's React WYSIWYG Editor</h3>
            <FroalaEditorComponent tag='textarea' />
        </div>
    );
}

export default FroalaComponent;

Step 5: Filestack Configuration

5.1: Create Filestack Account

In this step, we need to create a Filestack account and obtain a Filestack API key to add to the Froala configuration so we can upload files to your cloud storage through the Filestack File Picker. This powerful tool allows users to upload, store, and transform files directly. When integrated with Froala, it enables users to upload files from their local devices or cloud storage and apply various transformations within the Froala Editor interface.

You can create a free Filestack account with limited bandwidth, uploads, transformations, and storage, or start a free trial of a paid plan based on your needs.

create Filestack account

5.2: Set the Filestack Plugin Options

Login to your account and copy your Filestack API key.

Get Filestack API key

In the “FroalaComponent.jsx”, add a config parameter to FroalaEditorComponent where you can pass all the Froala configuration:

  • Set the filestackOptions.filestackAPI to your Filestack API key.
  • Set the filestackOptions.uploadToFilestackOnly to true. This will handle all file uploads by Filestack.
  • (Optional) If you want to customize the Filestack Picker, pass the File Picker configurations in the filestackOptions.pickerOptions option.
  • (Optional) Assign a callback function to the filestack.filestackPickerOpened event to perform a custom action after a user opens the Filestack File Picker.
  • (Optional) Assign a callback function to the filestack.filestackPickerClosed event to perform a custom action after a user closes the Filestack File Picker.
  • (Optional) Assign a callback function to the filestack.uploadedToFilestack event to perform a custom action when files are successfully uploaded to your cloud storage.
  • (Optional) Assign a callback function to the filestack.uploadFailedToFilestack event to perform a custom action if file upload fails.
import React, { useEffect } from 'react';
import 'froala-editor/css/froala_style.min.css';
import 'froala-editor/css/froala_editor.pkgd.min.css';
import FroalaEditorComponent from 'react-froala-wysiwyg';
import 'froala-editor/js/plugins.pkgd.min.js';

function FroalaComponent() {
    let config = {
        filestackOptions: {
            uploadToFilestackOnly: true,
            filestackAPI: "***",
        },

        events: {
            'filestack.uploadedToFilestack': function (response) {
                console.log("Callback is triggered for uploaded to filestack ",)
            },

            'filestack.filestackPickerOpened': function (response) {
                console.log("Callback is triggered for picker opened ",)
            },

            'filestack.filestackPickerClosed': function (response) {
                console.log("Callback is triggered for picker closed ",)
            },

            'filestack.uploadFailedToFilestack': function (response) {
                console.log("Callback is triggered for file stack failed ",)
            },

        },
    };
    useEffect(() => {
        const filestackScript1 = document.createElement('script');
        filestackScript1.src = 'https://static.filestackapi.com/filestack-js/3.32.0/filestack.min.js';
        filestackScript1.async = true;
        document.body.appendChild(filestackScript1);

        const filestackScript2 = document.createElement('script');
        filestackScript2.src = 'https://static.filestackapi.com/filestack-drag-and-drop-js/1.1.1/filestack-drag-and-drop.min.js';
        filestackScript2.async = true;
        document.body.appendChild(filestackScript2);

        const filestackScript3 = document.createElement('script');
        filestackScript3.src = 'https://static.filestackapi.com/transforms-ui/2.x.x/transforms.umd.min.js';
        filestackScript3.async = true;
        document.body.appendChild(filestackScript3);

        const filestackStylesheet = document.createElement('link');
        filestackStylesheet.rel = 'stylesheet';
        filestackStylesheet.href = 'https://static.filestackapi.com/transforms-ui/2.x.x/transforms.css';
        document.head.appendChild(filestackStylesheet);

        return () => {
            document.body.removeChild(filestackScript1);
            document.body.removeChild(filestackScript2);
            document.body.removeChild(filestackScript3);
            document.head.removeChild(filestackStylesheet);
        };
    }, []);

    return (
        <div className="editor">
            <h3>Froala's React WYSIWYG Editor</h3>
            <FroalaEditorComponent tag='textarea' config={config} />
        </div>
    );
}

export default FroalaComponent;

The “FroalaComponent.jsx” component can now be imported and used in other components of your React application.

5.3: Configure Cloud Storage

By default, all uploaded files are stored in Filestack’s internal S3 bucket. This doesn’t require any additional configuration and works for both free and paid Filestack accounts.

However, if you’re on a paid plan, you can store files in your custom cloud storage on the following platforms:

  • Amazon S3
  • Rackspace
  • Azure Blob Storage
  • Dropbox
  • Google Cloud Storage

Log in to your Filestack dev portal and follow the steps described here.

Step 6: Add Froala To Your Main Component

To display the Froala editor in your product, add the FroalaComponent to the template where you want the editor to be displayed.

In our tutorial, we will add it to the App.js file. It will be like

import './App.css';
import FroalaComponent from './components/FroalaComponent';

function App() {
  return (
    <div className="App">

      <FroalaComponent />
    </div>
  );
}

export default App;

 Step 7: Start Your Application

Open the terminal again and run the following command.

npm start

This will start the development server, which will display the Froala editor with Filestack buttons for uploading images, videos, and files.

Rich text-editor integrated with Filestack

Step 8: Test Your Application

You can test if your Filestack integration is working properly by following the below steps:

  • Upload images, videos, or files through Filestack File Picker.
  • Login to your Filestack dev portal.
  • Click on the “Content Browser“ and see if your files are listed.
  • Go to your cloud storage service and check if your file is successfully stored.

Conclusion

In this article, we’ve explored how to seamlessly integrate the Froala React Rich Text Editor with Filestack’s powerful file management capabilities within a React application. Filestack provides a user-friendly interface and a range of advanced image editing capabilities that can be easily integrated with the Froala editor.

The integration of Froala and Filestack streamlines the process of uploading, storing, and transforming files directly within the rich-text editor, empowering your users to focus on creating great content without the hassle of complex file management. With just a few simple steps, you can set up this integration and unlock advanced image editing tools, a user-friendly file picker, and a robust cloud storage solution.

So what are you waiting for? Try the Froala-Filestack integration and give your users the rich-text editing experience they deserve.

Get your Filestack API here for free.

 

How to make an ASP.NET HTML code writer with image resize capabilities

Image resolution is something that we sometimes overlook as developers. Basic functionality, error handling, and intuitiveness come first, after all. However, that doesn’t mean that handling image resolution or size isn’t important. In fact, improper image handling can slow down websites and applications, consume excessive bandwidth, or ruin the UI or UX. One good way to prevent this is by resizing uploaded images before they’re stored. So, let’s discover how we can build an HTML code writer with image resizing using ASP.NET, ImageMagick, and a WYSIWYG HTML editor.

Key Takeaways

  • Image resizing boosts performance by reducing load times and bandwidth usage.
  • ASP.NET, Froala, and ImageMagick are combined to build a web app with image resizing.
  • Froala Editor allows easy image uploads and rich text editing.
  • ImageMagick simplifies resizing, ensuring images fit set dimensions.
  • Customizable solution with options for validation, enhancement, and more.

Here’s a little demonstration of our HTML code writer’s image resize capability:

Notice how the 2 sample images had a landscape orientation before being uploaded and how they both changed afterwards. Now, read more to use an ASP.NET-based HTML code writer with image resizing capabilities. For more details, feel free to check our .NET image resize documentation. Now let’s set up the application.

Setting up the application

Before we get to the development part, let’s check out the tools that we’ll be using:

  • ASP.NET Core: An open-source web application framework that comes with Visual Studio
  • ImageMagick: An extensive open-source software suite for enhancing images
  • Froala: A powerful WYSIWYG HTML editor that supports HTML code editing, image uploads, Markdown, and more

 

Now that we know what we need, let’s do the following steps to create our project:

  1. Open Visual Studio and create a new project.
  2. Select the “ASP.NET Core Web App (Razor Pages) template. In our case, the project name is FroalaImageResizeDemo.
  3. Select “.NET 8.0 (Long Term Support)” as the framework.
  4. Click “Create”.

 

Next, let’s add the Froala Editor via CDN:

  1. Open the “_Layout.cshtml” file under the Pages > Shared directory.
  2. Add the Froala CDN links inside the <head> section.
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/froala-editor/4.3.0/css/froala_editor.pkgd.min.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/froala-editor/4.3.0/js/froala_editor.pkgd.min.js"></script>

Once we’ve included Froala in our project, we will be installing ImageMagick via NuGet Package Manager. 

  1. In the Solution Explorer, right-click the project name and select “Manage NuGet Packages.”
  2. Under the “Browse” tab, search for “Magick.NET-Q8-AnyCPU” and click the install button.

Finally, let’s create a folder where we can store the images. In the Solution Explorer, find the “wwwroot” folder. Create a new folder inside it named “images.” Now that we’ve configured our project setup, it’s time to create our image resizing HTML code writer.

Making the HTML code writer

First, let’s create a new page where we can initialize and load Froala Editor.

  1. Right-click the Pages folder.
  2. Select Add > New Item > Razor Page.
  3. Let’s name it “Editor.cshtml.”

 

Insert the following code to the newly created page:

 

@page
@model FroalaImageResizeDemo.Pages.EditorModel
@{
    ViewData["Title"] = "Froala Image Resize Demo";
}

<h2 class="mt-5 mb-3">@ViewData["Title"]</h2>

<div id="editor">For this demo, we're resizing all uploaded images to 600 px by 300 px.</div>


<script>
    new FroalaEditor('#editor', {
        imageUploadURL: '',
        heightMin: 600
    });
</script>

 

This page will contain the Froala editor as well as a header. The <div> with the “editor” ID is the container where we’ll load Froala. On the other hand, imageUploadURL is a Froala image upload option that determines where the upload request is made. For now, let’s leave that option blank, but we’ll get back to it later.

 

We now have a dedicated page for our HTML code writer. However, it’s still not reachable via navigation, so let’s fix that by adding a link:

  1. Open “_Layout.cshtml” again.
  2. Add the following code snippet to the <ul> within the navbar section:

 

                         

<li class="nav-item">
    <a class="nav-link text-dark" asp-page="/Editor">Froala Editor</a>
</li>

 

 

Afterwards, try running the application by pressing F5 or the play button. You should now have a glimpse of the default ASP.NET Core application with a “Froala Editor” link on the navbar. Click on it, and you’ll see Froala in action. You can now edit text, upload images, and perform other rich text actions. All that’s left now is to combine our HTML code writer with ImageMagick for image resizing.

 

Integrating ImageMagick for resizing images

To include ImageMagick’s resizing feature, we need to first create a new controller:

  1. Right-click the Controllers folder (create one if it wasn’t generated by the IDE).
  2. Select Add > New Item.
  3. Under the ASP.NET Core category, choose “API Controller – Empty.”
  4. Name it “FroalaApiController.cs” and click the add button.

 

Next, add the following code to the newly created controller:

 

using Microsoft.AspNetCore.Mvc;
using ImageMagick;

[Route("api/FroalaApi")]
[ApiController]
public class FroalaApiController : ControllerBase
{
    [HttpPost("UploadImageResize")]
    public IActionResult UploadImageResize()
    {
        // Check if the request contains files
        if (Request.Form.Files.Count == 0)
        {
            return BadRequest("No files were uploaded.");
        }

        var file = Request.Form.Files[0];

        if (file.Length > 0)
        {
            // Define the file path
            var filePath = Path.Combine(Directory.GetCurrentDirectory(),        "wwwroot", "images", file.FileName);

            // Save the file to the server
            using (var stream = new FileStream(filePath, FileMode.Create))
            {
                file.CopyTo(stream);
            }

            // Resize the image
            using (var image = new MagickImage(filePath))
            {
                var resizeGeometry = new MagickGeometry(600, 600)
                {
                    IgnoreAspectRatio = true
                };
                image.Resize(resizeGeometry);
                image.Write(filePath); // Save the resized image
            }

            return Ok(new { link = $"/images/{file.FileName}" });
        }

        return BadRequest("Failed to upload image.");
    }
}

 

Firstly, make sure to include “using ImageMagick” to enable it. We then check whether a file was successfully uploaded from the request or not. Then, we define the file path where we store our images (in our case, under wwwroot > images). Afterwards, we resize the image by declaring a new MagickImage object with our desired dimensions (600×600 pixels). Lastly, we return an HTTP 200 status code along with the JSON containing the image’s URL on success. Froala will then display the image within the editor, and we’re done!

 

 

Conclusion

Resizing images is a vital task for any application. For instance, we might need to limit image resolution for display purposes (e.g., email or blog images). We might also need to minimize image size for efficiency and cost reduction. However, image handling can be a pain sometimes. Fortunately, there are dozens of tools like ImageMagick that can help us easily accomplish that, as I’ve shown you in this HTML code writer demo.

 

By combining .NET, Froala, and ImageMagick, you can streamline the entire process of implementing image resizing in your applications. For your own projects, using the same tools, you can even take it up a notch. For example, you can add image quality enhancement, file type and size validation, autosaving, and more to make your application more robust. Now, it’s your turn to sprinkle some (Image)magic(K) on your projects!

Why Froala WYSIWYG HTML Editor Is The Best Lexical Alternative

WYSIWYG HTML Editor

Key Takeaways

Lexical is an extensible headless text editor framework, meaning we need to build the user interface ourselves. It has a limited number of ready-made features, though it is simple, lightweight, and offers the permissive MIT license. In contrast, Froala is a powerful WYSIWYG HTML editor with a wide range of basic and advanced features already implemented. It can be set up in under five minutes, allowing you to use it right away.

If you’re uncertain whether Froala or Lexical is the better fit for your project, this comparison will help you find the ideal solution. By the end of this article, you will clearly understand the key differences between Froala and Lexical.

The Best Lexical Alternative

Editor Setup and Initialization

To grasp the differences between Lexical and Froala, let’s explore how to basic setup them up by initializing each editor in Vanilla JS and examining their resulting interfaces.

In Lexical, the basic initialization code is

import {createEditor} from 'lexical';

const config = {
  namespace: 'MyEditor',
  theme: {
    ...
  },
  onError: console.error
};

const editor = createEditor(config);

const contentEditableElement = document.getElementById('editor');

editor.setRootElement(contentEditableElement);

This displays a very basic plain editable area to the users, with no toolbar or buttons to format the text. You still have to use the Lexical API to build the editor toolbar and add the required buttons one by one.

Lexical basic

For Froala, you simply include the Froala Stylesheet and JavaScript files, then call the initialization function.

   var editor = new FroalaEditor('#example');

This will display the full-featured editor, enabling users to rich-edit content, including advanced features like inserting videos, images, and tables.

Froala wysiwyg HTML editor

Built-in Features

Froala offers a wider range of features than Lexical, including more advanced rich-text editing capabilities. Additionally, Froala’s features are immediately available upon initialization, whereas Lexical requires extra steps to display them on the toolbars. Here’s a comparison between supported features in both editors.

FRO Lexical
Basic Formatting
text Color
background Color
clear Formatting
Paragraph Format
outdent
indent
quote
Markdown
Special Characters
Insert horizontal line
undo/redo
Character Counter
Word Counter
Link
Image
Video
Table
emoticons
print
Export as PDF
Spelling and Grammar Checker
Select All
Edit HTML code
Help
Quick insert buttons
Mentions
real-time collaboration
Paragraph Style
Code Block
Files manager
Table of Contents

 

Custom Features and Extensibility

Both Lexical and Froala offer powerful APIs that allow developers to extend their functionality through custom features and integrations. However, the level of effort required to do so differs between the two editors.

Integrations

Froala and Lexical are framework-agnostic editors, meaning they can be integrated with a wide variety of web development frameworks and libraries. However, the level of integration support and ease of use differs between the two editors.

Froala Integrations: Froala provides official SDKs and plugins to integrate the editor with popular front-end frameworks and libraries. These official integrations make it significantly easier to set up and customize the Froala editor within these frameworks. The SDKs handle the boilerplate code, event handling, and other integration details, allowing developers to focus on the core functionality.

Lexical Integrations: While Lexical is also framework-agnostic, it does not provide the same level of official integration support as Froala.

Integrating Lexical with a specific framework typically requires more manual setup and boilerplate code. This can result in more development time and effort, especially for projects that require tight integration with the surrounding application.

Client SDK
FRO Lexical
Angular
React
Vue
CakePHP
Craft CMS
Aurelia
Django
Ember JS
Gatsby JS
Meteor JS
Knockout JS
Rails
Sencha
Symfony
Yii Framework

In addition to client framework SDKs, Froala also offers server SDKs, making uploading images and videos to your server a piece of cake.

Server SDKs (uploading images and videos)
FRO Lexical
PHP
.NET
JAVA
Node.js
Python
Rails

In summary, Froala’s extensive integration support and official SDKs make it easier to set up and customize the editor within popular front-end frameworks, while Lexical requires more manual integration effort due to its more minimal, framework-agnostic approach.

License and Pricing

Lexical is an open-source project available under the MIT license, making it project-friendly. In contrast, using the Froala Editor requires purchasing one of its pricing plans based on your needs.

Lexical is free, but you will incur development costs to create and maintain your final solution, which may exceed the cost of Froala. Even if you are a developer, the time spent on development is a cost to consider.

Support

Froala is actively maintained by a dedicated professional team. It undergoes continuous development, with periodic releases that add new features and fix user-reported issues. For example, last week Froala V4.3 was released, which included a new, reliable advanced image editor as well as file uploading and cloud storage capabilities.

Froala vs. Lexical: Choosing the Optimal Rich Text Editing Solution for Your Project

Lexical’s API allows developers to create custom plugins and components to extend its functionality, but this requires more development effort compared to Froala’s built-in features. It’s the best solution if you don’t have money to buy Froala.

Froala, on the other hand, provides a wide range of pre-built plugins and customization options, making it easier to add new capabilities without extensive coding. This can be particularly beneficial for projects with limited development resources or tight timelines, as Froala’s comprehensive feature set can be leveraged more quickly.

Comparing an editor framework to a traditional editor may feel awkward, but we’ve aimed to provide helpful information to assist with your analysis. We suggest you supplement this comparison with your own research.

Before making your final choice, try Froala for free. The free trial provides you with all Froala features. Play, customize, choose wisely, and elevate your editing experience today!

New storage solutions available inside an HTML editor software

As developers, we’re constantly seeking tools to streamline workflows and boost application performance. With Froala Editor’s latest update, we’ve integrated Filestack’s powerful file handling capabilities within Froala WYSIWYG HTML Editor Software, opening up a world of possibilities for content creation and management. Let’s dive into what this means for you and your projects.

The File Handling Dilemma: Solved

Handling file uploads, large files, storage management, and fast content delivery used to be challenging. With this integration, those challenges are addressed.

Froala Editor’s integration with Filestack tackles these challenges head-on, providing a robust solution that’s as flexible as it is powerful. Whether you’re building a simple blog or a complex content management system, this integration has got you covered.

Key Takeaways

  • Froala WYSIWYG HTML editor software integrates with Filestack for advanced file handling and storage solutions.
  • Flexible storage options include default S3, Amazon S3, Google Cloud, Azure Blob, Dropbox, and more.
  • Filestack’s CDN provides fast, global content delivery with on-the-fly media optimizations.
  • Easy setup for custom cloud storage with straightforward configuration in Froala HTML editor software.
  • Scalable pricing plans and advanced file processing features make this integration ideal for projects of all sizes.

 

Flexible Storage: Your Files, Your Way

Recognizing that different projects have different storage needs, Filestack offers multiple options:

  1. Default S3 Storage: Out of the box, your files are safely tucked away in Filestack’s S3 bucket. It’s fast, it’s reliable, and it just works.
  2. Custom Cloud Storage: Need more control? No problem. Bring your own storage solution:
    • Amazon S3 (any region you like)
    • Google Cloud Storage (for the Google enthusiasts)
    • Azure Blob Storage (Microsoft fans, we see you)
    • Dropbox (for that personal touch)
    • Rackspace (oldies but goodies)

Moreover, you can switch between these storage options as your requirements change, without significant alterations to your application.

Setting Up Custom Storage: Simple Steps

Let’s say you want to use your own S3 bucket. All you need is the right IAM policy. Here’s a snippet to get you started:

 

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:GetObject",
                "s3:PutObject",
                "s3:PutObjectAcl",
                "s3:DeleteObject"
             ],
             "Resource": "arn:aws:s3:::YOUR_BUCKET_NAME/*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:ListAllMyBuckets",
                "s3:GetBucketLocation"
            ],
            "Resource": "arn:aws:s3:::*"
        }
    ]
}

 

Simply replace YOUR_BUCKET_NAME with your actual bucket name to complete the setup.

You can refer to Filestack’s complete documentation for the complete setup.

Once your custom storage is configured, Filestack’s performance optimization features come into play, ensuring your files are not only stored securely but also delivered efficiently across the globe.

Performance Optimization

Filestack’s CDN ensures content is delivered from servers closest to users, minimizing latency and maximizing speed. The ability to perform on-the-fly transformations means you can optimize media for different devices without storing multiple versions. Automatic scaling handled by Filestack ensures consistent performance under heavy loads.

Filestack’s CDN

Moreover, with Filestack’s CDN integration, your content is not only securely stored but also delivered across the internet with exceptional speed and efficiency.

Here’s how it works:

  1. Upload a file, get a unique URL pointing to Filestack’s CDN.
  2. Use this URL in your app, or get fancy with Filestack’s Processing API for on-the-fly transformations.
  3. Your content is now ready to be served blazingly fast to users around the globe.

Your content delivery speeds will significantly improve.

Real-World Applications: Two Implementation Scenarios

Scenario 1: The Bootstrapped Startup

Meet Sarah, who is building a collaborative writing platform with a limited budget. She starts with Froala Editor and Filestack’s default S3 storage, requiring no initial setup or upfront costs. As her user base grows, she leverages the CDN to maintain responsive performance during traffic spikes. When she secures a major client, she utilizes Filestack’s Processing API to implement on-the-fly watermarking for uploaded images. This allows her platform to scale seamlessly from an MVP to an enterprise-ready solution without altering the core infrastructure.

Scenario 2: The Enterprise Juggernaut

Big Corp is revamping its content management system and requires strict data control. They integrate Froala Editor with their existing Google Cloud Storage setup. Using Filestack’s CDN, they serve content globally, significantly reducing latency for international offices. To meet compliance standards, they implement custom file processing workflows via Filestack’s API, ensuring all uploaded documents are automatically scanned and encrypted. This approach provides enterprise-grade features without added complexity.

 

Implementing Filestack: Quick and Easy Configuration

To enhance your Froala Editor with Filestack integration, here’s a basic configuration to get you started:

var editor = new FroalaEditor('#editor', {
    filestackOptions: {
        filestackAPI: "YOUR_FILESTACK_API_KEY",
        uploadToFilestackOnly: false,
        pickerOptions: {
            accept: ["image/*", "video/*", "audio/*", ".pdf"],
            fromSources: ["local_file_system", "url", "googledrive", "dropbox"]
        }
    }
});

This snippet enables Filestack uploads in your Froala HTML editor software, allowing users to upload images, videos, audio files, and PDFs from their local system, URLs, Google Drive, or Dropbox. Customize it to fit your needs!

Pricing plans

Now, let’s talk numbers. While a Filestack free plan is available for initial exploration, the paid plans unlock the full potential:

  • Start: $69/month Perfect for small projects or MVPs. (75GB bandwidth, 20,000 uploads, 50,000 transformations, 50GB storage)
  • Grow: $199/month Ideal for growing startups and medium-sized businesses. (200GB bandwidth, 50,000 uploads, 150,000 transformations, 150GB storage)
  • Scale: $379/month For the big players with heavy content needs. (400GB bandwidth, 125,000 uploads, 300,000 transformations, 350GB storage)

Each plan comes with a free trial, so you can try before you buy.

The Road Ahead

The integration of Filestack with Froala Editor is more than just a feature update. It’s a whole new way of thinking about content in your web applications.

Consider the following possibilities:

  • Your users can drag and drop files from their cloud storage directly into your app.
  • Images are automatically optimized for different devices and network conditions.
  • Videos are transcoded on-the-fly to support all browsers.
  • Documents are securely stored and delivered with enterprise-grade reliability.

These features are currently available with Froala Editor and Filestack.

Wrapping Up

This overview highlights just a portion of what is possible with this integration. Whether you’re a solo developer working on a passion project or part of a large team building the next big thing, Froala Editor with Filestack gives you the tools to handle files like a pro.

We encourage you to explore this integration and discover how it can enhance your projects. Your users will appreciate the improved experience.

In web development, content is paramount. With Froala Editor and Filestack, you can fully leverage your content’s potential.

Additional Resources

Froala 4.3: Advanced Image & Video Upload and Transformation Features

Advanced Image uploads

We are super excited to announce the latest and greatest milestone update for our WYSIWYG HTML Editor. Froala Editor V4.3 introduces integration with the powerful file upload and management platform, Filestack. This integration made by the new Filestack plugin offers a more reliable and faster file-uploading process. Moreover, it offers numerous file transformations all can be applied within the Froala editor.

In addition to the Filestack integration, this release also includes significant quality improvements based on valuable feedback from our users. We’ve worked hard to enhance the overall user experience.

Let’s explore the new Filestack plugin, how it works, and what it can do.

Froala V4.3

Filestack Integration

The Filestack plugin serves as the bridge between Froala and Filestack, enabling Froala users to leverage the powerful features offered by Filestack within their editing experience.

The Filestack plugin is optional. The default Froala Image and File features will remain the default options. The Filestack plugin can be activated for users who are looking for:

  • Faster and 99.99% reliable upload experience.
  • Easy integration with web storage providers.
  • Easy and fast delivery through a reliable CDN.
  • Advanced Image and File transformation capabilities.

To use the “Filestack” plugin, you should use your Filestack account. If you do not have a Filestack account, create one to obtain a Filestack API key. Your Filestack plan and the features you enabled from the Filestack marketplace determine your Filestack plugin’s enabled features. The Filestack plugin requires your API Key to be provided in the filestackOptions.filestackAPI option.

When the Filestack Plugin is active, you have two modes based on the filestackOptions.uploadToFilestackOnly option.

  1. Basic Implementation mode (Default Mode)
  2. Advanced Implementation mode (when filestackOptions.uploadToFilestackOnly is set to true)

Filestack Basic Implementation

This Basic mode introduces Filestack’s picker and transformation UI to the existing Froala users without affecting their existing workflow. Filestack file picker and Transformation UI will add to the existing options for image, video, and file upload and image transformations.

Upload

When the user clicks on Froala’s “Insert Image,” “Insert Video,” “Insert File,” or “File Manager” option from the toolbar, the displayed popup will have an option for upload through Filestack.

Basic image upload mode

Selecting the Filestack option will display the Filestack File Picker tool, allowing users to pick and upload files directly to Filestack and insert them into the Froala editor.

A new API option, filestackOptions.pickerOptions, has been added allowing you to pass the File Picker configuration such as allowed file types and sources for uploads. You can utilize this option to customize the File Picker experience.

     var editor = new FroalaEditor('#editor', {
       filestackOptions: {
            /*
            To get your Filestack API, create a free Filestack account
            https://www.filestack.com/signup-free-froala/
            */
            filestackAPI: "**************",
            uploadToFilestackOnly: false,


            pickerOptions: {
                accept: [
                    ".pdf",
                    "image/jpeg",
                    "image/png",
                    "image/*",
                    "video/*",
                    "audio/*"
                ],
                fromSources: [
                    "local_file_system",
                    "url",
                    "facebook",
                    "instagram"
                ]
            },
            transformationOptions: {
                filters: {
                    enabled: [
                        "blackWhite",
                        "sepia"
                    ]
                },
                adjustments: {
                    enabled: [
                        "brightness",
                        "noise"
                    ]
                }
            }
        }
    });

Replace

Froala’s image and video edit popups will feature a new button to replace files via Filestack.

Filestack replace image

Image Transformations

Filestack offers many image transformations that can be applied through Filestack’s transformation UI.

In this release, a new “Transform“ button was added to Froala’s image edit popup. This option can be used with any image inserted in the editor through Filestack.

Filestack transformation UI

Using this option, Froala users will be able to enhance any uploaded image using Filestack’s enhanced Image transformations UI. Users can transform their images by applying filters, adjusting image sizes, and performing many other image transformations. When the Froala user saves their changes, the image is replaced with the transformed version.
Here is a working example of Filestack’s basic mode integration.

Filestack Advanced Implementation

Filestack advanced mode will enforce Filestack options for all file upload features in Froala, replacing the default options on toolbars. Advanced implementation mode can be enabled by setting the configuration filestackOptions.uploadToFilestackOnly to true while initializing the editor (by default, this config will be false).

    var editor = new FroalaEditor('#editor', {

       filestackOptions: {
            uploadToFilestackOnly: true,
            filestackAPI: '****',
        },

    });

Upload

Enabling Filestack’s advanced implementation mode will replace the default Insert Image, Video, File, and File Manager buttons on the main toolbar with Filestack upload buttons for images, videos, and files.

Fraola advanced file upload mode

Clicking these buttons opens the Filestack picker, enabling users to select and upload files to their Filestack account.

File Picker

In this mode, dragging and dropping files into the Froala Editor will upload files to Filestack directly and insert them into the Editor as long as the Filestack subscription is active.

Replace

The image edit and video edit popups will still have the same options they have in the basic mode, including the replace option.

Image Transformations

This works the same as the Image Transformation options of Basic Implementation.

Why Filestack

Filestack’s tools and powerful APIs allow users to upload, store, transform, and deliver content easily. Filestack’s Picker integration gives users a rich experience to quickly and seamlessly pick files from different sources. Filestack’s scalable infrastructure powers millions of uploads, transformations, and downloads every month, providing great performance to users worldwide.

Configure Filestack Plugin

To activate the Filestack plugin, consider the following:

  • The Filestack File Picker and Transformation UI stylesheet and JavaScript files are included.
  <script src="https://static.filestackapi.com/filestack-js/3.32.0/filestack.min.js"></script>
  <script src="https://static.filestackapi.com/filestack-drag-and-drop-js/1.1.1/filestack-drag-and-drop.min.js"></script>
  <script src="https://static.filestackapi.com/transforms-ui/2.x.x/transforms.umd.min.js"></script>
  <link rel="stylesheet" href="https://static.filestackapi.com/transforms-ui/2.x.x/transforms.css" />
  • The plugin’s JavaScript file is included. If you’re using the packaged version of the Froala editor, you can skip this step.
 <link rel="stylesheet" type="text/css" href="dist/css/froala_editor.pkgd.min.css">
 <!-- Load main JS file. -->
 <script type="text/javascript" src="../dist/js/froala_editor.min.js"></script> 
 <!-- Filestack JS file. -->
 <script type="text/javascript" src="../dist/js/plugins/filestack.min.js"></script>
  • Include Froala’s Filestack plugin in the pluginsEnabled option if you are customizing this option.
  • Set the filestackOptions.filestackAPI option to your Filestack API. To get your Filestack API, create a free Filestack account.
  • Set filestackOptions.uploadToFilestackOnly to true if you want to turn on the advanced mode.
  • (optional) set filestackOptions.filestackOptions option based on your preferences.
    var editor = new FroalaEditor('#edit', {

        imageEditButtons: ['imageReplace', 'imageAlign', 'imageCaption', 'filestackIcon', 'imageTUI'],

        filestackOptions: {
            uploadToFilestackOnly: false,
            filestackAPI: '****',
            pickerOptions: {

                accept: [
                    ".pdf",
                    "image/jpeg",
                    "image/png",
                    "image/webp",
                    "video/*",
                    "audio/*"
                ],
                transformations: {
                    "crop": true,

                }
            },

        },

        events: {
            'filestack.uploadedToFilestack': function (response) {
                console.log("Callback is triggered for uploaded to filestack ",)
            },

            'filestack.filestackPickerOpened': function (response) {
                console.log("Callback is triggered for picker opened ",)
            },

            'filestack.filestackPickerClosed': function (response) {
                console.log("Callback is triggered for picker closed ",)
            },

            'filestack.uploadFailedToFilestack': function (response) {
                console.log("Callback is triggered for file stack failed ",)
            },

        },

    });

By configuring the Filestack plugin, you can provide your users with the rich file upload, transformation, and delivery capabilities of Filestack within the Froala Editor. Users can easily access Filestack’s features, such as picking files from various sources, applying image transformations, and replacing existing content. The advanced implementation mode offers a seamless, Filestack-centric experience, streamlining the content creation workflow. Filestack’s scalable infrastructure and powerful APIs ensure reliable performance and a smooth user experience, empowering Froala users to create and manage their content efficiently.
Here is a working example of Filestack’s advanced mode integration.

Is Filestack Free?

Froala users can sign up for a free plan that offers generous usage limits. If you require more usage, Filestack offers various pricing plans, each of which includes a 21-day free trial. Check the available plans on Filestack.

Other Improvements Included in The 4.3 Release

In addition to the Filestack integration, Froala Editor 4.3 includes several other improvements to enhance the user experience. These include:

Counting Special Characters and Emojis Toward the Character Limit

In Froala, developers can limit the number of characters a user can enter in the editor using the charCounterMax option. Now even special characters and emojis are counted, allowing developers to set more accurate character limits for their content. Now, users will be aware of the true character count, including special characters and emojis, as they type. This helps them stay within the desired character limits.

Fixing Font Family and Font Size Issues When Integrating with Craft CMS

The Craft CMS framework’s CSS conflicted with the Froala editor’s styles, resulting in incorrect font family and font size for the editor content. The Froala team has resolved this issue, ensuring that the conflict no longer occurs.

Bug Fixes

We’ve addressed several user-reported bugs and issues to improve the user experience even better. These include:

  • Resolved the issue where an additional scrollbar appears when opening the emoticons popup on certain screen resolutions.
  • Resolved the issue occurs when a user tries to select a link using the combination of the left arrow key and the Shift key, resulting in an “Uncaught DOMException” error.
  • Resolved the issue where setting fontSizeDefaultSelection in the config results in multiple wrapper divs being added to the content on subsequent edits.

Please find the complete changelog list here.

How Can I Update?

Don’t miss out on the benefits of the latest Froala 4.3 release. Update today and experience the enhanced editing features and improvements.

If you are using a plain JavaScript library or other framework, check the get started page to know how to download the latest Froala Editor release and how to include it in your project based on your preferred method.

If you are using a plain JavaScript library or other framework, follow the table below to learn how to download the latest Froala Editor release and include it in your project based on your preferred method.

Method How to download Include in your project
CDN
<!-- Include Editor stylesheet-->
<link href="https://cdn.jsdelivr.net/npm/[email protected]/css/froala_editor.pkgd.min.css" rel="stylesheet" type="text/css" />

<!-- Include Editor JavaScript file-->
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/[email protected]/js/froala_editor.pkgd.min.js"></script>
CDN (Always the latest version)
<!-- Include Editor stylesheet-->
<link href="https://cdn.jsdelivr.net/npm/froala-editor@latest/css/froala_editor.pkgd.min.css" rel="stylesheet" type="text/css" />

<!-- Include Editor JavaScript file-->
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/froala-editor@latest/js/froala_editor.pkgd.min.js"></script>
NPM
npm install froala-editor
<!--

Replace the {download-folder-path} in the following example with the path to the folder containing the stylesheet file e.g.

../css/froala_editor.pkgd.min.js

-->

<link href="{download-folder-path}/froala_editor.pkgd.min.css" rel="stylesheet" type="text/css" />

<!--

Replace the {download-folder-path} with the path to the folder containing the JS file e.g.

../js/froala_editor.pkgd.min.js

-->

<script type="text/javascript" src="{download-folder-path}/froala_editor.pkgd.min.js"></script>
bower
bower install froala-wysiwyg-editor
NO Package Manager Download Froala WYSIWYG Editor files using the download form here.
Integrated with a Framework Select your preferred framework from 17 different popular frameworks.
Other options Check here for other options to use Froala WYSIWYG Editor in your project.

For Froala Editor Version 2 Users:

Follow this migration guide for step-by-step instructions on upgrading from version 2.

Try The Latest Froala Editor

Explore a variety of examples that demonstrate the functionality of the Froala HTML Editor.

Support and Feedback

We are dedicated to always offering the best possible experience for all our users. We believe this release, meant to enhance Typescript support, is a stepping stone towards that commitment. We encourage you to try this improved Typescript support and give us your valuable feedback. Your input is crucial for delivering continuous enhancement in meeting your evolving needs. Thank you for being a valuable part of our vibrant and growing community.
We would like to hear what you think of the latest release! Join us on our GitHub Community to chat with our product manager, developers, and other members of the Froala team.

Change Log

Get Started

  • You can download and start using Froala in less than five minutes following our get-started guide.

Technical Questions

Get your Filestack API here for free.

Enhancing Your HTML Code Writer by Adding Cool Features with Plugins

As web developers, we’re always on the lookout for ways to make our work easier and faster.  WYSIWYG HTML editors are great tools that help us create web content without having to write every bit of code by hand. But did you know we can make these tools even better? Let’s explore how plugins can add some awesome new features to your HTML code writer.

Key Takeaways:

  • Plugins can add lots of new features to WYSIWYG HTML editors
  • Adding media from social sites becomes super easy
  • Writing with Markdown can speed things up
  • Customizing your editor can make your work smoother
  • It’s important to think about how plugins affect performance

Embedding Rich Media Content

The Power of Social Media Integration

First off, let’s talk about making your content more interesting. One cool thing you can add to your HTML code writer is the ability to easily put in stuff from social media sites. This means you can add tweets, Facebook posts, or Instagram pictures without having to mess around with complicated code.

Setting Up Embedly in Froala Editor

For instance, if you’re using Froala Editor, you can add something called Embedly. It’s like a magic wand that lets you add content from over 500 different websites. Here’s how you might set it up:

<script src="https://cdn.embedly.com/widgets/platform.js" charset="UTF-8"></script>
<link rel="stylesheet" href="../css/third_party/embedly.min.css">
<script src="https://cdn.jsdelivr.net/npm/froala-editor@latest/js/third_party/embedly.min.js"></script>

Then, you can turn on the Embedly feature like this:

new FroalaEditor('#editor', {
  toolbarButtons: [['bold', 'italic', 'underline'], ['embedly', 'html']]
});

Now, you can easily add cool media to your content with just a few clicks. This is super helpful when you’re making blog posts or web pages that need lots of pictures or videos.

Streamlining Content Creation with Markdown

Introduction to Markdown

Next, let’s talk about Markdown. If you haven’t heard of it, Markdown is a simple way to format text that a lot of developers love. It’s fast and easy to use, and you don’t have to keep switching between your keyboard and mouse.

Enabling Markdown in Froala Editor

If you’re using Froala, you can add Markdown support like this:

new FroalaEditor('#editor', {
  toolbarButtons: ['bold', 'italic', 'underline', 'paragraphFormat', 'align', 'markdown']
});

With this setup, you can switch between regular editing and Markdown mode. This means you can choose whichever way is faster for what you’re working on at the moment.

Real-World Applications

Now, let’s look at some ways these new features can be really useful:

  1. Building Websites: If you’re making a website where people can add their own content, the media embedding feature lets them easily add pictures and videos without knowing any code.
  2. Writing Instructions: When you’re writing instructions for how to use your code, the Markdown feature can help you quickly add headers and code examples.
  3. Team Projects: If you’re working with a team, having both regular editing and Markdown options means everyone can work in the way they like best.
  4. Quick Projects: When you need to put together a project fast, being able to quickly add media and format text can save you a lot of time.

Considerations When Adding Plugins

While adding new features to your HTML code writer is exciting, there are a few things to keep in mind:

  1. Speed: Adding too many features can make your editor slow to load. Only add the ones you’ll really use.
  2. Ease of Use: Think about who will be using the editor. If they’re not familiar with Markdown, for example, it might be confusing for them.
  3. Working Together: Make sure all the new features you add work well together and with the rest of your project.
  4. Keeping Things Updated: Remember, each new feature you add is something else you’ll need to keep updated over time.

Exploring Advanced Features

HTML code writers can do more than just edit text. With the right plugins, you can add all sorts of helpful features. For example, some editors let you add:

  • Tools for working together in real-time
  • Connections to version control systems
  • Checkers to make sure your content is accessible to everyone
  • Tools to help your content show up better in search engines

Conclusion

Adding new features to your HTML code writer can make your work a lot easier and faster. These additions let you create better content more quickly, whether you’re working on your own or with a team.

Remember, the goal is to make your work easier, not more complicated. Try out different features and setups to find what works best for you.

By making the most of your HTML code writer, you can spend more time creating great content and less time worrying about the technical details. With the right mix of features, your editor can become a powerful tool for all your web development needs. Happy coding!