diff --git a/src/app/previewengine.cpp b/src/app/previewengine.cpp
index 1f50ca8a00350f0ed4b58c442135c82aa070f770..8aa570eb21b6e09163a76719540a9379ed4e29c2 100644
--- a/src/app/previewengine.cpp
+++ b/src/app/previewengine.cpp
@@ -18,6 +18,7 @@
 #include "previewengine.h"
 
 #include <QRegularExpression>
+#include <QThread>
 
 const QRegularExpression PreviewEngine::newlineRe("\\r?\\n");
 
@@ -25,10 +26,21 @@ PreviewEngine::PreviewEngine(ConnectivityMonitor* cm, QObject* parent)
     : NetworkManager(cm, parent)
     , htmlParser_(new HtmlParser(this))
 {
+    // Run this object in a separate thread.
+    thread_ = new QThread();
+    moveToThread(thread_);
+    thread_->start();
+
     // Connect on a queued connection to avoid blocking caller thread.
     connect(this, &PreviewEngine::parseLink, this, &PreviewEngine::onParseLink, Qt::QueuedConnection);
 }
 
+PreviewEngine::~PreviewEngine()
+{
+    thread_->quit();
+    thread_->wait();
+}
+
 QString
 PreviewEngine::getTagContent(const QList<QString>& tags, const QString& value)
 {
diff --git a/src/app/previewengine.h b/src/app/previewengine.h
index 38435c6369fe398fba1ebeb9977954ccf365931a..0ba009e192deed0d2195f3fc5ab19dbd04c1ecbb 100644
--- a/src/app/previewengine.h
+++ b/src/app/previewengine.h
@@ -27,7 +27,7 @@ class PreviewEngine final : public NetworkManager
     Q_DISABLE_COPY(PreviewEngine)
 public:
     PreviewEngine(ConnectivityMonitor* cm, QObject* parent = nullptr);
-    ~PreviewEngine() = default;
+    ~PreviewEngine();
 
 Q_SIGNALS:
     void parseLink(const QString& messageId, const QString& link);
@@ -45,4 +45,6 @@ private:
     QString getImage(const QList<QString>& metaTags);
 
     static const QRegularExpression newlineRe;
+
+    QThread* thread_;
 };