How to transform your LMS with a React WYSIWYG HTML editor, part 2
Posted on By Aaron Dumon | Last updated on | In General,
Table of contents
- Key takeaways
- Recap: Part 1 of building the React WYSIWYG HTML editor
- Understanding the data flow: From SQL Server to React
- Loading uploaded content into your React WYSIWYG HTML editor
- Creating the API endpoint for fetching content
- Loading the content on the front end
- Populating the React WYSIWYG HTML editor with the fetched content
- Looking ahead: Next steps in transforming your LMS
Last time, we explored how to make a simple but powerful LMS using a React WYSIWYG HTML editor. This tool not only enhances the user experience for LMS applications but also simplifies content creation for whoever needs it. In the previous article, we built our application using React and used Froala to create the contents of a courseโs chapter. Moreover, we delved into the file upload and transformation features of the natively integrated Filestack file picker. If you missed our previous discussion, check out our article on creating the React WYSIWYG HTML editor-powered LMS. In this part, weโll dive deeper into how Froala works. Specifically, weโll load the content that we saved in Part 1 back to the editor from SQL Server.
Key takeaways
- Building from the code in Part 1, we added a new PHP file as well as a new component for loading the contents of a chapter.
- We also edited FroalaComponent so that it now loads an initial content.
- Loading previously saved content back to Froala Editor on a React application takes little time and effort.
- Loaded content will appear exactly as they were saved, ensuring integrity and clarity within your LMS.
- You can load Filestack-stored content together with the editor or independently from it.
Recap: Part 1 of building the React WYSIWYG HTML editor
In Part 1, we created a React application called demo-lms. We also had five components, which handled loading and saving courses, loading and saving chapters, and initializing the editor. For the FroalaEditor component, we also initialized Filestack by creating a free Filestack account and including the API key in the editor config. Finally, we created some endpoints for fetching and saving data from and to SQL Server using PHP. Now, weโll load the contents of a chapter back to the React application and into the editor.
Understanding the data flow: From SQL Server to React
Note that in our chapterย table, we have a column for a chapterโs ID, title, description, contents, publishing date, and an optional URL for a Filestack upload. To display these, we would have to write PHP code and load them via a simple SELECT query. From there, we will fetch the data from our React application with the chapter ID as the parameter and set the result as an object. That leaves us with assigning each property of the object to a DOM element. Ready to start?
Loading uploaded content into your React WYSIWYG HTML editor
Creating the API endpoint for fetching content
First, letโs create our new PHP file and name it getChapterById.php. Inside it, paste the following code:
<?php
header('Access-Control-Allow-Origin: http://localhost:3000');
header("Access-Control-Allow-Methods: GET, POST, OPTIONS");
header("Access-Control-Allow-Headers: Content-Type, Authorization");
header("Content-Type: application/json");
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
header("HTTP/1.1 200 OK");
exit();
}
include "connection.php";
if (isset($_GET["chapterId"])) {
$chapterId = $_GET["chapterId"];
$query = "SELECT chapter_title, chapter_description, chapter_content, chapter_img_url, date_published FROM chapter WHERE chapter_id = ?";
$params = array($chapterId);
$stmt = sqlsrv_query($conn, $query, $params);
if($stmt === false){
http_response_code(500);
echo json_encode(["error" => "Failed to query the database."]);
exit;
}
$chapter = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC);
if($chapter){
echo json_encode($chapter);
}
else{
http_response_code(404);
echo json_encode(["message" => "Chapter not found"]);
}
sqlsrv_free_stmt($stmt);
sqlsrv_close($conn);
}
else{
echo json_encode(["message" => "Chapter ID not provided"]);
}
?>
This file looks a lot like the other ones we created in Part 1, except weโre now getting the chapter details from the chapter table. Donโt forget to configure your headers to prevent CORS errors. Furthermore, in a real application, you would want to have proper input and error handling, as well as more security measures than just query parameterization. After creating the PHP file, letโs move back to the front end.
Loading the content on the front end
To load the saved content back to the application, letโs first edit our current App.js and include these lines:
// other imports
import ChapterDetails from './components/ChapterDetails'
function App() {
return (
<Router>
<Routes>
...other routes from Part 1 go here
<Route path="/chapterDetails/:courseId/:chapterId" element={<ChapterDetails />} />
</Routes>
</Router>
);
}
Weโve added an extra import for the ChapterDetails component, which weโll create shortly, and another route to load the new component. Afterwards, weโll want our users to navigate to the new components from the Chapters view. To do that, insert the following button to the DOM:
<Link to={`/chapterDetails/${course.course_id}/${chapter.chapter_id}`}>
<button>Details</button>
</Link>
This button allows users to navigate to the new component with the course and chapter IDs as the parameters. The next thing we have to do is create our ChapterDetails.jsx component and add the code below:
import React, { useState, useEffect } from 'react';
import { useParams } from 'react-router-dom';
import { Link } from 'react-router-dom';
import FroalaComponent from './FroalaComponent';
function ChapterDetails() {
const { courseId, chapterId } = useParams();
const [chapter, setChapter] = useState(null);
// Fetch details for the chapter
const fetchChapterDetails = async () => {
const response = await fetch(`http://localhost:8081/demo-lms-backend/getChapterById.php?chapterId=${chapterId}`);
const data = await response.json();
setChapter(data);
};
useEffect(() => {
fetchChapterDetails();
}, [chapterId]);
if (!chapter) {
return <p>Loading chapter details...</p>;
}
const handleSetChapterContent = (content) => {
console.log("Chapter content set:", content);
};
return (
<div>
<h1>Chapter Details</h1>
<Link to={`/chapters/${courseId}`}>
<button>Back to Chapters</button>
</Link>
<div >
<div className="chapter-card">
<h3>{chapter.chapter_title}</h3>
<p>{chapter.chapter_description}</p>
<FroalaComponent initialContent={chapter.chapter_content} setChapterContent={handleSetChapterContent} />
<p>This is how the Filestack URL will appear if stored separately in the database: <a href={chapter.chapter_img_url}>{chapter.chapter_img_url}</a></p>
<p>Date Published: {chapter.date_published ? new Date(chapter.date_published.date).toLocaleDateString() : 'N/A'}</p>
</div>
</div>
</div>
);
}
export default ChapterDetails;
Here are a few things that we should note:
- Weโre also importing FroalaComponent here to load the editor.
- Pass the chapterId parameter to the backend to retrieve the data. In a real LMS, you might want to pair that with the courseId if your primary key consists of both IDs.
- We initialize our FroalaComponent with an initialContent property this time. This allows the editor to display content once initialized. Thus, we pass chapter.chapter_content as the parameter.
After creating our new component, letโs populate the React WYSIWYG HTML editor with the chapterโs contents.
Populating the React WYSIWYG HTML editor with the fetched content
To populate the editor, we need to edit FroalaComponent by adding the initialContent property that we used in the previous step. Replace:
function FroalaComponent({ setChapterContent, setChapterImage}) {
...
}
With:
function FroalaComponent({ setChapterContent, setChapterImage, initialContent}) {
...
}
Afterwards, replace
<FroalaEditorComponent tag='textarea' config={config} />
With:
<FroalaEditorComponent tag='textarea' config={config} model={initialContent} />
And weโre done! You should now see the chapter details, including its contents, when clicking the โDetailsโ button on a chapter card. The following images demonstrate the new additions to our sample LMS:


In the โChapter Detailsโ view, youโll see a button for going back to the course details as well as the chapterโs title, description, contents, and publishing date. Additionally, youโll see that you can load contents uploaded using Filestack on the editor itself or separately. Below the editor, we loaded the URL for a document (โDemo Document.pdf) after a sentence. This shows Filestackโs flexibility, giving you control over how you want to display or download your data. After clicking either the โDemo Document.pdfโ link on the editor or the Filestack CDN link below, youโll see the following:

Now, weโve discovered how we can load contents using Filestack CDN, React, and Froala for our sample LMS. Thatโs another step closer to having an exceptional editing tool with file upload and transformation capabilities within your LMS!
Looking ahead: Next steps in transforming your LMS
In this second part of our LMS journey, we explored how to load saved content from SQL Server into our React WYSIWYG HTML editor. We created a new component and API endpoint and updated the old ones as well. By adding and editing a few lines of code, we were able to fetch the contents of a course chapter and accurately display them into the editor. In Part 3, we will discuss additional functionalities, including editing the content within the Froala editor. Additionally, weโll try out the other transformation features of Filestack. See you again soon!
Get your Filestack API here for free.

Aaron Dumon
Aaron Dumon is an expert technical writer focusing on JavaScript WYSIWYG HTML Editors.
- Whats on this page hide




No comment yet, add your voice below!