diff --git a/app/Entities/Controllers/BookApiController.php b/app/Entities/Controllers/BookApiController.php
index 41ff11dde..aa21aea47 100644
--- a/app/Entities/Controllers/BookApiController.php
+++ b/app/Entities/Controllers/BookApiController.php
@@ -45,7 +45,7 @@ class BookApiController extends ApiController
 
         $book = $this->bookRepo->create($requestData);
 
-        return response()->json($book);
+        return response()->json($this->forJsonDisplay($book));
     }
 
     /**
@@ -56,9 +56,9 @@ class BookApiController extends ApiController
      */
     public function read(string $id)
     {
-        $book = Book::visible()
-            ->with(['tags', 'cover', 'createdBy', 'updatedBy', 'ownedBy'])
-            ->findOrFail($id);
+        $book = Book::visible()->findOrFail($id);
+        $book = $this->forJsonDisplay($book);
+        $book->load(['createdBy', 'updatedBy', 'ownedBy']);
 
         $contents = (new BookContents($book))->getTree(true, false)->all();
         $contentsApiData = (new ApiEntityListFormatter($contents))
@@ -89,7 +89,7 @@ class BookApiController extends ApiController
         $requestData = $this->validate($request, $this->rules()['update']);
         $book = $this->bookRepo->update($book, $requestData);
 
-        return response()->json($book);
+        return response()->json($this->forJsonDisplay($book));
     }
 
     /**
@@ -108,21 +108,35 @@ class BookApiController extends ApiController
         return response('', 204);
     }
 
+    protected function forJsonDisplay(Book $book): Book
+    {
+        $book = clone $book;
+        $book->unsetRelations()->refresh();
+
+        $book->load(['tags', 'cover']);
+        $book->makeVisible('description_html')
+            ->setAttribute('description_html', $book->descriptionHtml());
+
+        return $book;
+    }
+
     protected function rules(): array
     {
         return [
             'create' => [
-                'name'        => ['required', 'string', 'max:255'],
-                'description' => ['string', 'max:1000'],
-                'tags'        => ['array'],
-                'image'       => array_merge(['nullable'], $this->getImageValidationRules()),
+                'name'                => ['required', 'string', 'max:255'],
+                'description'         => ['string', 'max:1900'],
+                'description_html'    => ['string', 'max:2000'],
+                'tags'                => ['array'],
+                'image'               => array_merge(['nullable'], $this->getImageValidationRules()),
                 'default_template_id' => ['nullable', 'integer'],
             ],
             'update' => [
-                'name'        => ['string', 'min:1', 'max:255'],
-                'description' => ['string', 'max:1000'],
-                'tags'        => ['array'],
-                'image'       => array_merge(['nullable'], $this->getImageValidationRules()),
+                'name'                => ['string', 'min:1', 'max:255'],
+                'description'         => ['string', 'max:1900'],
+                'description_html'    => ['string', 'max:2000'],
+                'tags'                => ['array'],
+                'image'               => array_merge(['nullable'], $this->getImageValidationRules()),
                 'default_template_id' => ['nullable', 'integer'],
             ],
         ];
diff --git a/app/Entities/Controllers/BookshelfApiController.php b/app/Entities/Controllers/BookshelfApiController.php
index 9bdb8256d..a12dc90ac 100644
--- a/app/Entities/Controllers/BookshelfApiController.php
+++ b/app/Entities/Controllers/BookshelfApiController.php
@@ -12,11 +12,9 @@ use Illuminate\Validation\ValidationException;
 
 class BookshelfApiController extends ApiController
 {
-    protected BookshelfRepo $bookshelfRepo;
-
-    public function __construct(BookshelfRepo $bookshelfRepo)
-    {
-        $this->bookshelfRepo = $bookshelfRepo;
+    public function __construct(
+        protected BookshelfRepo $bookshelfRepo
+    ) {
     }
 
     /**
@@ -48,7 +46,7 @@ class BookshelfApiController extends ApiController
         $bookIds = $request->get('books', []);
         $shelf = $this->bookshelfRepo->create($requestData, $bookIds);
 
-        return response()->json($shelf);
+        return response()->json($this->forJsonDisplay($shelf));
     }
 
     /**
@@ -56,12 +54,14 @@ class BookshelfApiController extends ApiController
      */
     public function read(string $id)
     {
-        $shelf = Bookshelf::visible()->with([
-            'tags', 'cover', 'createdBy', 'updatedBy', 'ownedBy',
+        $shelf = Bookshelf::visible()->findOrFail($id);
+        $shelf = $this->forJsonDisplay($shelf);
+        $shelf->load([
+            'createdBy', 'updatedBy', 'ownedBy',
             'books' => function (BelongsToMany $query) {
                 $query->scopes('visible')->get(['id', 'name', 'slug']);
             },
-        ])->findOrFail($id);
+        ]);
 
         return response()->json($shelf);
     }
@@ -86,7 +86,7 @@ class BookshelfApiController extends ApiController
 
         $shelf = $this->bookshelfRepo->update($shelf, $requestData, $bookIds);
 
-        return response()->json($shelf);
+        return response()->json($this->forJsonDisplay($shelf));
     }
 
     /**
@@ -105,22 +105,36 @@ class BookshelfApiController extends ApiController
         return response('', 204);
     }
 
+    protected function forJsonDisplay(Bookshelf $shelf): Bookshelf
+    {
+        $shelf = clone $shelf;
+        $shelf->unsetRelations()->refresh();
+
+        $shelf->load(['tags', 'cover']);
+        $shelf->makeVisible('description_html')
+            ->setAttribute('description_html', $shelf->descriptionHtml());
+
+        return $shelf;
+    }
+
     protected function rules(): array
     {
         return [
             'create' => [
-                'name'        => ['required', 'string', 'max:255'],
-                'description' => ['string', 'max:1000'],
-                'books'       => ['array'],
-                'tags'        => ['array'],
-                'image'       => array_merge(['nullable'], $this->getImageValidationRules()),
+                'name'             => ['required', 'string', 'max:255'],
+                'description'      => ['string', 'max:1900'],
+                'description_html' => ['string', 'max:2000'],
+                'books'            => ['array'],
+                'tags'             => ['array'],
+                'image'            => array_merge(['nullable'], $this->getImageValidationRules()),
             ],
             'update' => [
-                'name'        => ['string', 'min:1', 'max:255'],
-                'description' => ['string', 'max:1000'],
-                'books'       => ['array'],
-                'tags'        => ['array'],
-                'image'       => array_merge(['nullable'], $this->getImageValidationRules()),
+                'name'             => ['string', 'min:1', 'max:255'],
+                'description'      => ['string', 'max:1900'],
+                'description_html' => ['string', 'max:2000'],
+                'books'            => ['array'],
+                'tags'             => ['array'],
+                'image'            => array_merge(['nullable'], $this->getImageValidationRules()),
             ],
         ];
     }
diff --git a/app/Entities/Controllers/ChapterApiController.php b/app/Entities/Controllers/ChapterApiController.php
index 7f01e445a..c21323262 100644
--- a/app/Entities/Controllers/ChapterApiController.php
+++ b/app/Entities/Controllers/ChapterApiController.php
@@ -15,18 +15,20 @@ class ChapterApiController extends ApiController
 {
     protected $rules = [
         'create' => [
-            'book_id'     => ['required', 'integer'],
-            'name'        => ['required', 'string', 'max:255'],
-            'description' => ['string', 'max:1000'],
-            'tags'        => ['array'],
-            'priority'    => ['integer'],
+            'book_id'          => ['required', 'integer'],
+            'name'             => ['required', 'string', 'max:255'],
+            'description'      => ['string', 'max:1900'],
+            'description_html' => ['string', 'max:2000'],
+            'tags'             => ['array'],
+            'priority'         => ['integer'],
         ],
         'update' => [
-            'book_id'     => ['integer'],
-            'name'        => ['string', 'min:1', 'max:255'],
-            'description' => ['string', 'max:1000'],
-            'tags'        => ['array'],
-            'priority'    => ['integer'],
+            'book_id'          => ['integer'],
+            'name'             => ['string', 'min:1', 'max:255'],
+            'description'      => ['string', 'max:1900'],
+            'description_html' => ['string', 'max:2000'],
+            'tags'             => ['array'],
+            'priority'         => ['integer'],
         ],
     ];
 
@@ -61,7 +63,7 @@ class ChapterApiController extends ApiController
 
         $chapter = $this->chapterRepo->create($requestData, $book);
 
-        return response()->json($chapter->load(['tags']));
+        return response()->json($this->forJsonDisplay($chapter));
     }
 
     /**
@@ -69,9 +71,15 @@ class ChapterApiController extends ApiController
      */
     public function read(string $id)
     {
-        $chapter = Chapter::visible()->with(['tags', 'createdBy', 'updatedBy', 'ownedBy', 'pages' => function (HasMany $query) {
-            $query->scopes('visible')->get(['id', 'name', 'slug']);
-        }])->findOrFail($id);
+        $chapter = Chapter::visible()->findOrFail($id);
+        $chapter = $this->forJsonDisplay($chapter);
+
+        $chapter->load([
+            'createdBy', 'updatedBy', 'ownedBy',
+            'pages' => function (HasMany $query) {
+                $query->scopes('visible')->get(['id', 'name', 'slug']);
+            }
+        ]);
 
         return response()->json($chapter);
     }
@@ -93,7 +101,7 @@ class ChapterApiController extends ApiController
             try {
                 $this->chapterRepo->move($chapter, "book:{$requestData['book_id']}");
             } catch (Exception $exception) {
-                if ($exception instanceof  PermissionsException) {
+                if ($exception instanceof PermissionsException) {
                     $this->showPermissionError();
                 }
 
@@ -103,7 +111,7 @@ class ChapterApiController extends ApiController
 
         $updatedChapter = $this->chapterRepo->update($chapter, $requestData);
 
-        return response()->json($updatedChapter->load(['tags']));
+        return response()->json($this->forJsonDisplay($updatedChapter));
     }
 
     /**
@@ -119,4 +127,16 @@ class ChapterApiController extends ApiController
 
         return response('', 204);
     }
+
+    protected function forJsonDisplay(Chapter $chapter): Chapter
+    {
+        $chapter = clone $chapter;
+        $chapter->unsetRelations()->refresh();
+
+        $chapter->load(['tags']);
+        $chapter->makeVisible('description_html')
+            ->setAttribute('description_html', $chapter->descriptionHtml());
+
+        return $chapter;
+    }
 }
diff --git a/app/Entities/Models/Book.php b/app/Entities/Models/Book.php
index 52674d839..14cb790c5 100644
--- a/app/Entities/Models/Book.php
+++ b/app/Entities/Models/Book.php
@@ -31,7 +31,7 @@ class Book extends Entity implements HasCoverImage
     public float $searchFactor = 1.2;
 
     protected $fillable = ['name'];
-    protected $hidden = ['pivot', 'image_id', 'deleted_at'];
+    protected $hidden = ['pivot', 'image_id', 'deleted_at', 'description_html'];
 
     /**
      * Get the url for this book.
diff --git a/app/Entities/Models/Bookshelf.php b/app/Entities/Models/Bookshelf.php
index 464c127b8..9ffa0ea9c 100644
--- a/app/Entities/Models/Bookshelf.php
+++ b/app/Entities/Models/Bookshelf.php
@@ -19,7 +19,7 @@ class Bookshelf extends Entity implements HasCoverImage
 
     protected $fillable = ['name', 'description', 'image_id'];
 
-    protected $hidden = ['image_id', 'deleted_at'];
+    protected $hidden = ['image_id', 'deleted_at', 'description_html'];
 
     /**
      * Get the books in this shelf.
diff --git a/app/Entities/Models/Chapter.php b/app/Entities/Models/Chapter.php
index 6c5f059ac..f30d77b5c 100644
--- a/app/Entities/Models/Chapter.php
+++ b/app/Entities/Models/Chapter.php
@@ -20,7 +20,7 @@ class Chapter extends BookChild
     public float $searchFactor = 1.2;
 
     protected $fillable = ['name', 'description', 'priority'];
-    protected $hidden = ['pivot', 'deleted_at'];
+    protected $hidden = ['pivot', 'deleted_at', 'description_html'];
 
     /**
      * Get the pages that this chapter contains.
diff --git a/dev/api/responses/books-read.json b/dev/api/responses/books-read.json
index 21e1829b8..afeebade6 100644
--- a/dev/api/responses/books-read.json
+++ b/dev/api/responses/books-read.json
@@ -3,6 +3,7 @@
   "name": "My own book",
   "slug": "my-own-book",
   "description": "This is my own little book",
+  "description_html": "<p>This is my own <em>little</em> book</p>",
   "created_at": "2020-01-12T14:09:59.000000Z",
   "updated_at": "2020-01-12T14:11:51.000000Z",
   "created_by": {
diff --git a/dev/api/responses/chapters-read.json b/dev/api/responses/chapters-read.json
index 5f4de85f1..192ffce7c 100644
--- a/dev/api/responses/chapters-read.json
+++ b/dev/api/responses/chapters-read.json
@@ -4,6 +4,7 @@
   "slug": "content-creation",
   "name": "Content Creation",
   "description": "How to create documentation on whatever subject you need to write about.",
+  "description_html": "<p>How to create <strong>documentation</strong> on whatever subject you need to write about.</p>",
   "priority": 3,
   "created_at": "2019-05-05T21:49:56.000000Z",
   "updated_at": "2019-09-28T11:24:23.000000Z",
diff --git a/dev/api/responses/shelves-read.json b/dev/api/responses/shelves-read.json
index 802045bd8..eca06a46b 100644
--- a/dev/api/responses/shelves-read.json
+++ b/dev/api/responses/shelves-read.json
@@ -3,6 +3,7 @@
   "name": "My shelf",
   "slug": "my-shelf",
   "description": "This is my shelf with some books",
+  "description_html": "<p>This is my shelf with some books</p>",
   "created_by": {
     "id": 1,
     "name": "Admin",