diff --git a/android/AndroidManifest.xml b/android/AndroidManifest.xml
index 509e7625ae9146eb1ab484c74883da3f22538657..ccd0a95af41a2d7f876262f730d50b0422a066a7 100644
--- a/android/AndroidManifest.xml
+++ b/android/AndroidManifest.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0"?>
 <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="io.qt.qtdesignviewer"
-    android:installLocation="auto" android:versionCode="25" android:versionName="1.2">
+    android:installLocation="auto" android:versionCode="26" android:versionName="1.2">
     <!-- %%INSERT_PERMISSIONS -->
     <!-- %%INSERT_FEATURES -->
     <supports-screens android:anyDensity="true" android:largeScreens="true"
diff --git a/src/backend.cpp b/src/backend.cpp
index 78ce526f42ad8ec69bf85b22ba5e5d241468322a..e74167329361c795e4fdcf4a22660488ec9a00fc 100644
--- a/src/backend.cpp
+++ b/src/backend.cpp
@@ -336,16 +336,18 @@ void Backend::runDemoProject(const QString &projectName)
 
     // sample project info
     // [{"lastUpdate":1701947766739.9812,"name":"ClusterTutorial.qmlrc"}]
-    const QJsonArray projectList = m_serviceConnector.fetchUserDemoList();
+    const std::optional<QJsonArray> projectList = m_serviceConnector.fetchDemoList();
 
-    if (projectList.isEmpty()) {
-        qCritical("Please check your internet connection and try again");
+    if (projectList == std::nullopt) {
+        qCritical()
+            << "Could not fetch demo project list. Please check your internet connection and "
+               "try again.";
         emit popupClose();
         return;
     }
 
     QJsonObject projectInfo;
-    for (auto project : projectList) {
+    for (auto project : projectList.value()) {
         if (projectName == project.toObject().value("name").toString().remove(".qmlrc")) {
             projectInfo = project.toObject();
             break;
@@ -357,13 +359,18 @@ void Backend::runDemoProject(const QString &projectName)
     if (!cached) {
         updatePopup("Downloading demo project...", false);
 
-        const QString url = "https://designviewer.qt.io/qmlprojects/demos/" + projectName
-                            + ".qmlrc";
-        QByteArray project = m_serviceConnector.fetchProject(url);
-        qDebug() << "Demo project is not cached. Trying to download from " << url << " ...";
+        const std::optional<QByteArray> project = m_serviceConnector.fetchDemo(projectName
+                                                                               + ".qmlrc");
+
+        if (project == std::nullopt) {
+            qCritical() << "Could not download demo project. Please check the logs for more "
+                           "information.";
+            emit popupClose();
+            return;
+        }
 
         updatePopup("Caching demo project...");
-        if (!m_projectManager->cacheDemoProject(project, projectInfo)) {
+        if (!m_projectManager->cacheDemoProject(project.value(), projectInfo)) {
             qCritical()
                 << "Could not cache demo project. Please check the logs for more information.";
             emit popupClose();
@@ -405,10 +412,11 @@ void Backend::runUserProject(const QString &projectName)
     const QString userHash = Backend::userHash();
 
     qDebug("Checking if project is cached. Getting list of available projects...");
-    const QJsonArray projectList = m_serviceConnector.fetchUserProjectList(userHash);
+    const std::optional<QJsonArray> projectList = m_serviceConnector.fetchUserProjectList(userHash);
 
-    if (projectList.isEmpty()) {
-        qCritical("Please check your internet connection and try again");
+    if (projectList == std::nullopt) {
+        qCritical() << "Could not fetch up-to-date project information. Please check your internet "
+                       "connection and try again.";
         emit popupClose();
         return;
     }
@@ -416,7 +424,7 @@ void Backend::runUserProject(const QString &projectName)
     QString projectLastModified;
     QString projectId;
     QJsonObject projectInfo;
-    for (auto project : projectList) {
+    for (auto project : projectList.value()) {
         if (projectName == project.toObject().value("appName").toString()) {
             projectInfo = project.toObject();
             break;
@@ -428,10 +436,18 @@ void Backend::runUserProject(const QString &projectName)
     if (!projectCached) {
         qDebug("Project is not cached. Downloading...");
         updatePopup("Project is not cached. Downloading...", false);
-        QByteArray projectData = m_serviceConnector.fetchUserProject(userHash, projectName);
+        const std::optional<QByteArray> projectData
+            = m_serviceConnector.fetchUserProject(userHash, projectName);
+
+        if (projectData == std::nullopt) {
+            qCritical()
+                << "Could not download project. Please check the logs for more information.";
+            emit popupClose();
+            return;
+        }
 
         updatePopup("Caching user project...");
-        if (!m_projectManager->cacheProject(projectData, projectInfo)) {
+        if (!m_projectManager->cacheProject(projectData.value(), projectInfo)) {
             qCritical() << "Could not cache project. Please check the logs for more information.";
             emit popupClose();
             return;
@@ -455,14 +471,16 @@ void Backend::runOnlineProject(const QString &url)
     initializeProjectManager();
     emit popupOpen();
     updatePopup("Downloading...", false);
-    QByteArray projectData = m_serviceConnector.fetchProject(url);
-    if (projectData.isEmpty()) {
+    const std::optional<QByteArray> projectData = m_serviceConnector.fetchProject(url);
+
+    if (projectData == std::nullopt) {
         qCritical() << "Could not download project. Please check the logs for more information.";
+        emit popupClose();
         return;
     }
 
     updatePopup("Unpacking project...");
-    QString projectPath = m_projectManager->unpackProject(projectData);
+    QString projectPath = m_projectManager->unpackProject(projectData.value());
     updatePopup("Running project...");
 
     if (!m_projectManager->runProject(projectPath))
@@ -484,16 +502,16 @@ void Backend::updateUserProjectList()
     }
 
     qDebug() << "Fetching available project list for user:" << userHash;
-    QJsonArray projectList = m_serviceConnector.fetchUserProjectList(userHash);
+    const std::optional<QJsonArray> projectList = m_serviceConnector.fetchUserProjectList(userHash);
 
-    if (projectList == m_projectList) {
+    if (projectList == std::nullopt) {
+        qWarning(
+            "Could not fetch project list. Please check your internet connection and try again.");
+    } else if (projectList.value() == m_projectList) {
         qDebug("No new projects are available");
-    } else if (projectList.isEmpty()) {
-        qWarning("Could not fetch project list. Either there are no projects or there is a "
-                 "network issue");
     } else {
         qDebug("List of available projects fetched:");
-        for (const auto &project : projectList) {
+        for (const auto &project : projectList.value()) {
             const QString projectName{project.toObject().value("appName").toString()};
             qDebug() << "--" << projectName;
         }
@@ -502,7 +520,7 @@ void Backend::updateUserProjectList()
     // we need to set m_projectList even if it is empty
     // because this triggers the onModelChanged function in the QML
     // in order to update the UI
-    m_projectList = projectList;
+    m_projectList = projectList.value();
     emit projectListChanged();
 }
 
diff --git a/src/projectManager.cpp b/src/projectManager.cpp
index b60006e7c3d305f2113d3503d47393404e671626..f7cf843a1fc8ef84fe74cae3c2e7f314a7c66c5f 100644
--- a/src/projectManager.cpp
+++ b/src/projectManager.cpp
@@ -81,7 +81,7 @@ void ProjectManager::cleanupResources()
                  << " Size: " << m_projectData.size() << " bytes.";
         data = reinterpret_cast<const uchar *>(m_projectData.data());
         if (!QResource::unregisterResource(data, m_projectPath)) {
-            qCritical("Cannot unregister the previous resource data.");
+            qCritical() << "Cannot unregister the previous resource data.";
         }
     }
 }
@@ -124,8 +124,8 @@ QString ProjectManager::unpackProject(const QByteArray &project, bool extractZip
         }
 
         if (!QResource::registerResource(data, resourcePath)) {
-            qCritical("Can not load the resource data.");
-            return "";
+            qCritical() << "Can not load the resource data.";
+            return {};
         }
 
         projectPath = ":" + resourcePath;
diff --git a/src/serviceConnector.cpp b/src/serviceConnector.cpp
index 01ec60a0db378509a0939a74a3d088687012f80e..d8ced5d8d0d32dbe737af9ffe47fa13fed67ff9d 100644
--- a/src/serviceConnector.cpp
+++ b/src/serviceConnector.cpp
@@ -31,7 +31,7 @@
 #include <QJsonDocument>
 #include <QJsonObject>
 
-QByteArray ServiceConnector::fetchResource(const QString &url, const bool quite)
+std::optional<QByteArray> ServiceConnector::fetchResource(const QString &url)
 {
     qDebug() << "Fetching resource from" << url;
 
@@ -42,10 +42,7 @@ QByteArray ServiceConnector::fetchResource(const QString &url, const bool quite)
                      &QNetworkReply::sslErrors,
                      this,
                      [&](const QList<QSslError> &errors) {
-                         if (!quite)
-                             qCritical() << errors.first().errorString();
-                         else
-                             qWarning() << errors.first().errorString();
+                         qWarning() << errors.first().errorString();
                      });
 
     QEventLoop loop;
@@ -63,47 +60,42 @@ QByteArray ServiceConnector::fetchResource(const QString &url, const bool quite)
     loop.exec();
 
     if (reply->error() != QNetworkReply::NoError) {
-        if (!quite)
-            qCritical() << reply->errorString();
-        else
-            qWarning() << reply->errorString();
-    } else {
-        qDebug() << "Resource fetched successfully";
+        qWarning() << reply->errorString();
+        return {};
     }
 
+    qDebug() << "Resource fetched successfully";
     return reply->readAll();
 }
 
-QByteArray ServiceConnector::fetchProject(const QString &url)
+std::optional<QByteArray> ServiceConnector::fetchProject(const QString &url)
 {
     QString projectUrl = url;
-    if (projectUrl.startsWith("https://designviewer.qt.io/#"))
-    {
+    if (projectUrl.startsWith(m_serviceUrl + "/#")) {
         projectUrl = projectUrl.split("#").at(1);
-        projectUrl.prepend("https://designviewer.qt.io/qmlprojects/");
+        projectUrl.prepend(m_serviceUrl + "/qmlprojects/");
     }
 
     return fetchResource(projectUrl);
 }
 
-QByteArray ServiceConnector::fetchUserProject(const QString &userHash, const QString &projectName)
+std::optional<QByteArray> ServiceConnector::fetchUserProject(const QString &userHash,
+                                                             const QString &projectName)
 {
-    const QString projectUrl = "https://designviewer.qt.io/qmlprojects/" + userHash + "/"
-                               + projectName + ".qmlrc";
+    const QString projectUrl = m_serviceUrl + "/qmlprojects/" + userHash + "/" + projectName
+                               + ".qmlrc";
+
     return fetchResource(projectUrl);
 }
 
-QJsonArray ServiceConnector::fetchUserProjectList(const QString &userHash)
+std::optional<QJsonArray> ServiceConnector::fetchUserProjectList(const QString &userHash)
 {
-    auto reply = fetchResource("https://designviewer.qt.io/api/v1/qmlrc/list/" + userHash
-                                   + "?key=818815",
-                               true);
+    auto reply = fetchResource(m_serviceUrl + "/api/v1/qmlrc/list/" + userHash + "?key=818815");
 
-    if (reply.size() == 0) {
-        return QJsonArray();
-    }
+    if (!reply)
+        return {};
 
-    QJsonArray projectList = QJsonDocument::fromJson(reply)
+    QJsonArray projectList = QJsonDocument::fromJson(reply.value())
                                  .object()
                                  .value("data")
                                  .toObject()
@@ -113,12 +105,16 @@ QJsonArray ServiceConnector::fetchUserProjectList(const QString &userHash)
     return projectList;
 }
 
-QJsonArray ServiceConnector::fetchUserDemoList()
+std::optional<QJsonArray> ServiceConnector::fetchDemoList()
 {
-    auto reply = fetchResource("https://designviewer.qt.io/api/v1/demos");
-    if (reply.size() == 0) {
-        return QJsonArray();
-    }
+    auto reply = fetchResource(m_serviceUrl + "/api/v1/demos");
+    if (!reply)
+        return {};
 
-    return QJsonDocument::fromJson(reply).array();
+    return QJsonDocument::fromJson(reply.value()).array();
+}
+
+std::optional<QByteArray> ServiceConnector::fetchDemo(const QString &demoName)
+{
+    return fetchResource(m_serviceUrl + "/qmlprojects/demos/" + demoName + ".qmlrc");
 }
diff --git a/src/serviceConnector.h b/src/serviceConnector.h
index ad0c4d9b5beafb7915fc15622195a44c94fd0cb4..3ee827deeb921ee5a7fb51f4def1f49579762985 100644
--- a/src/serviceConnector.h
+++ b/src/serviceConnector.h
@@ -33,14 +33,17 @@ class ServiceConnector : public QObject
 {
     Q_OBJECT
 public:
-    QByteArray fetchProject(const QString &url);
-    QByteArray fetchUserProject(const QString &userHash, const QString &projectName);
-    QJsonArray fetchUserProjectList(const QString &userHash);
-    QJsonArray fetchUserDemoList();
+    std::optional<QByteArray> fetchProject(const QString &url);
+    std::optional<QByteArray> fetchUserProject(const QString &userHash, const QString &projectName);
+    std::optional<QJsonArray> fetchUserProjectList(const QString &userHash);
+    std::optional<QJsonArray> fetchDemoList();
+    std::optional<QByteArray> fetchDemo(const QString &demoName);
 
 private:
     QNetworkAccessManager m_manager;
-    QByteArray fetchResource(const QString &url, const bool quite = false);
+    std::optional<QByteArray> fetchResource(const QString &url);
+
+    const QString m_serviceUrl = "https://designviewer.qt.io";
 
 signals:
     void downloadProgress(float percentage);