diff --git a/CMakeLists.txt b/CMakeLists.txt
index 82acd636913c818503dbca06b479c1deaa7ca2e4..724bb5547caa46f54d2c6e9b13b48d3d383ccf83 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -23,7 +23,7 @@ find_package(
     REQUIRED
 )
 
-set(QT_MINIMUM_VERSION 6.3.0)
+set(QT_MINIMUM_VERSION 6.6.0)
 if(QT_VERSION VERSION_LESS QT_MINIMUM_VERSION)
     message(FATAL_ERROR "Minimum supported Qt version: ${QT_MINIMUM_VERSION}")
 endif()
@@ -40,8 +40,22 @@ target_link_libraries(${PROJECT_NAME} PRIVATE
     Qt6::Qml Qt6::GuiPrivate
 )
 
-set_property(TARGET ${PROJECT_NAME}
-    APPEND PROPERTY QT_WASM_INITIAL_MEMORY "50MB"
+## FIXME: cannot enable exceptions in wasm
+# target_compile_options(${PROJECT_NAME} PRIVATE
+    # -fwasm-exceptions
+# )
+
+target_link_options(${PROJECT_NAME} PRIVATE
+    # -fwasm-exceptions
+    # -sEXPORT_EXCEPTION_HANDLING_HELPERS=1
+    # -sEXCEPTION_STACK_TRACES=1
+    -sEXCEPTION_DEBUG=1
+    -sFULL_ES3=1
+    -sABORT_ON_WASM_EXCEPTIONS=0
+)
+
+set_target_properties(${PROJECT_NAME} PROPERTIES
+    QT_WASM_INITIAL_MEMORY 2048MB
 )
 
 qt6_import_qml_plugins(${PROJECT_NAME})
@@ -59,7 +73,7 @@ install(
     DIRECTORY ${CMAKE_SOURCE_DIR}/www/
     DESTINATION ${CMAKE_INSTALL_PREFIX}
 )
-
+# END --install configuration
 
 execute_process(COMMAND git describe --always --tags OUTPUT_VARIABLE GIT_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE)
 execute_process(COMMAND git -C ${CMAKE_SOURCE_DIR}/qtquickdesigner-components describe --always --tags OUTPUT_VARIABLE QT_QUICK_COMPONENTS_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE)
@@ -72,5 +86,6 @@ message(STATUS "QT_QUICK_COMPONENTS_VERSION: ${QT_QUICK_COMPONENTS_VERSION}")
 message(STATUS "EMSDK_VERSION: ${EMSDK_VERSION}")
 message(STATUS "QT_VERSION: ${QT_VERSION}")
 
+add_definitions( -DCMAKE_VAR_GIT_VERSION="${GIT_VERSION}" )
+
 set_property(DIRECTORY APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES ${CMAKE_INSTALL_PREFIX})
-# END --install configuration
diff --git a/cicd/gitlab-ci.yml b/cicd/gitlab-ci.yml
index 1299a52056a8d675fcaae1ad858d57e3277afd3b..64ce51a2090709dcfa3149c7b1cbc92a70725f7b 100644
--- a/cicd/gitlab-ci.yml
+++ b/cicd/gitlab-ci.yml
@@ -1,7 +1,8 @@
 variables:
-  QDS_CI_QT_VERSION:
-    value: "6.6.1"
-    description: "Qt version for build"
+  # QT version and emsdk version must be compatible.
+  # See https://doc.qt.io/qt-6/wasm.html
+  QDS_CI_QT_VERSION: "6.6.1"
+  QDS_CI_EMSDK_VERSION: "3.1.37"
   QDS_CI_ARTIFACTS_PATH: "${CI_PROJECT_DIR}/artifacts"
   DEBIAN_FRONTEND: non-interactive
   GIT_SUBMODULE_STRATEGY: recursive
diff --git a/cicd/stages/build.yml b/cicd/stages/build.yml
index ba4b2313f617f30eecb4f45759c8ac077bbda3eb..d236bb84c05026b15dd9b13db9a80136dcd39a06 100644
--- a/cicd/stages/build.yml
+++ b/cicd/stages/build.yml
@@ -21,8 +21,8 @@ build-wasm:
     - mkdir -p ${QDS_CI_ARTIFACTS_PATH}
     - |
       cd emsdk
-      ./emsdk install 3.1.37
-      ./emsdk activate 3.1.37
+      ./emsdk install ${QDS_CI_EMSDK_VERSION}
+      ./emsdk activate ${QDS_CI_EMSDK_VERSION}
       source emsdk_env.sh
       cd ..
     - echo ${DOCKER_ENV_QT_PATH_WASM_SINGLETHREAD}
diff --git a/src/designviewer.cpp b/src/designviewer.cpp
index 7eb3fe6f8f9e474e9979874208ae9172b47e057a..228ed446042a8f48b9646ac6f4b944e4b7bb6586 100644
--- a/src/designviewer.cpp
+++ b/src/designviewer.cpp
@@ -46,8 +46,6 @@
 #include <QtGui/private/qzipreader_p.h>
 #endif
 
-#define printErr(x) printError(x, __FILE_NAME__, __LINE__)
-
 std::function<void(char *, size_t, char *)> g_setFileDataCallback;
 extern "C" EMSCRIPTEN_KEEPALIVE void qt_callSetFileData(char *content,
                                                         size_t contentSize,
@@ -62,26 +60,26 @@ extern "C" EMSCRIPTEN_KEEPALIVE void qt_callSetFileData(char *content,
 
 DesignViewer::DesignViewer()
 {
-    printLog("DesignViewer constructor");
+    qDebug() << "DesignViewer constructor";
     QString projectFileName;
     QByteArray projectData;
-    printLog("Fetching project");
+    qDebug() << "Fetching project";
     fetchProject(&projectData, &projectFileName);
-    printLog("Running project");
+    qDebug() << "Running project";
     if (!runProject(projectData, projectFileName)) {
-        printErr("Failed to run project");
+        qCritical() << "Failed to run project";
     }
-    printLog("DesignViewer constructor done");
+    qDebug() << "DesignViewer constructor done";
 }
 
 void DesignViewer::fetchProject(QByteArray *data, QString *fileName)
 {
-    printLog("Init project data");
+    qDebug() << "Init project data";
     // Access global variables set by index.html
     emscripten::val jsData = emscripten::val::global("contentArray");
     emscripten::val jsFileName = emscripten::val::global("projectfileName");
 
-    printLog("Copying project data");
+    qDebug() << "Copying project data";
     // Copy project data to the C++ heap and convert string
     *data = QByteArray::fromEcmaUint8Array(jsData);
     *fileName = QString::fromStdString(jsFileName.as<std::string>());
@@ -91,8 +89,7 @@ QString DesignViewer::unpackProject(const QByteArray &project, bool extractZip)
 {
     QString projectLocation = "/home/web_user/";
 
-    if (extractZip)
-    {
+    if (extractZip) {
         QDir().mkpath(projectLocation);
         QBuffer buffer;
         buffer.setData(project);
@@ -101,42 +98,38 @@ QString DesignViewer::unpackProject(const QByteArray &project, bool extractZip)
         reader.extractAll(projectLocation);
     }
 
-    printLog("Initial project location: " + projectLocation);
+    qDebug() << "Initial project location: " + projectLocation;
 
     QDir projectLocationDir(projectLocation);
 
     // maybe it was not a zip file so try it as resource binary
-    if (projectLocationDir.isEmpty())
-    {
+    if (projectLocationDir.isEmpty()) {
         if (extractZip)
-            printLog("File could not be extracted. Trying to open it as a resource file.");
+            qDebug() << "File could not be extracted. Trying to open it as a resource file.";
 
         const uchar *data;
-        if (m_projectData.size())
-        {
-            printLog("Unregistering the previous data from QRC system. Path: " + m_projectPath + " Size: " + QString::number(m_projectData.size()) + " bytes.");
+        if (m_projectData.size()) {
+            qDebug() << "Unregistering the previous data from QRC system. Path: " + m_projectPath
+                            + " Size: " + QString::number(m_projectData.size()) + " bytes.";
             data = reinterpret_cast<const uchar *>(m_projectData.data());
-            if (!QResource::unregisterResource(data, m_projectPath))
-            {
-                printErr("Cannot unregister the previous resource data.");
+            if (!QResource::unregisterResource(data, m_projectPath)) {
+                qCritical() << "Cannot unregister the previous resource data.";
             }
         }
 
         m_projectData = project;
         data = reinterpret_cast<const uchar *>(m_projectData.data());
-        printLog("Registering resource data. Size: " + QString::number(m_projectData.size()));
+        qDebug() << "Registering resource data. Size: " + QString::number(m_projectData.size());
 
         const QString resourcePath{"/" + QString::number(QRandomGenerator::global()->generate())};
         m_projectPath = resourcePath;
 
-        if (!QDir(resourcePath).removeRecursively())
-        {
-            printLog("Could not remove resource path: " + resourcePath);
+        if (!QDir(resourcePath).removeRecursively()) {
+            qDebug() << "Could not remove resource path: " + resourcePath;
         }
 
-        if (!QResource::registerResource(data, resourcePath))
-        {
-            printErr("Can not load the resource data.");
+        if (!QResource::registerResource(data, resourcePath)) {
+            qCritical() << "Can not load the resource data.";
             return "";
         }
 
@@ -161,9 +154,8 @@ void DesignViewer::parseQmlprojectFile(const QString &fileName,
      * need to keep the only ":" character at the beginning of the string
      */
     QFile file(fileName);
-    if (!file.open(QIODevice::ReadOnly))
-    {
-        printErr("Could not open Qml Project file! " + fileName + ": " + file.errorString());
+    if (!file.open(QIODevice::ReadOnly)) {
+        qCritical() << "Could not open Qml Project file! " + fileName + ": " + file.errorString();
         return;
     }
 
@@ -172,13 +164,12 @@ void DesignViewer::parseQmlprojectFile(const QString &fileName,
     const QRegularExpression mainFileRegExp("mainFile:\\s*\"(.*)\"");
     const QRegularExpressionMatch mainFileMatch = mainFileRegExp.match(text);
 
-    if (!mainFileMatch.hasMatch())
-    {
-        printErr("No main file found in " + fileName);
+    if (!mainFileMatch.hasMatch()) {
+        qCritical() << "No main file found in " + fileName;
         return;
     }
 
-    printLog("Found main file: " + mainFileMatch.captured(1));
+    qDebug() << "Found main file: " + mainFileMatch.captured(1);
     QString basePath = QFileInfo(fileName).path() + "/";
 
     *mainFile = basePath + mainFileMatch.captured(1);
@@ -189,8 +180,8 @@ void DesignViewer::parseQmlprojectFile(const QString &fileName,
     const QRegularExpressionMatch qt6ProjectMatch = qt6ProjectRegExp.match(text);
     if (!qt6ProjectMatch.hasMatch())
     {
-        printWarn("This is not a Qt6 project.\nQt5 projects might work, but they are not "
-                  "officially supported.");
+        qWarning() << "This is not a Qt6 project.\nQt5 projects might work, but they are not "
+                      "officially supported.";
     }
 
     const QRegularExpression importPathsRegExp("importPaths:\\s*\\[\\s*(.*)\\s*\\]");
@@ -198,12 +189,10 @@ void DesignViewer::parseQmlprojectFile(const QString &fileName,
 
     if (importPathsMatch.hasMatch())
     {
-        for (const QString &path : importPathsMatch.captured(1).split(","))
-        {
+        for (const QString &path : importPathsMatch.captured(1).split(",")) {
             QString cleanedPath = path.trimmed();
             cleanedPath = basePath + cleanedPath.mid(1, cleanedPath.length() - 2);
-            if (QFileInfo::exists(cleanedPath))
-            {
+            if (QFileInfo::exists(cleanedPath)) {
                 if (cleanedPath.startsWith(QLatin1String(":/")))
                     cleanedPath = "qrc:" + cleanedPath.mid(1);
                 importPaths->append(cleanedPath);
@@ -218,118 +207,107 @@ bool DesignViewer::runProject(const QByteArray &projectData, const QString &proj
     QString newProjectName = QString(projectName).remove(".qmlrc");
 
     if (newProjectName.contains("/")) {
-        printLog("Project name contains a path. Removing it.");
+        qDebug() << "Project name contains a path. Removing it.";
         newProjectName = newProjectName.split("/").last();
     }
 
-    printLog("Final project location: " + projectLocation);
-    printLog("Original project name: " + projectName);
-    printLog("New project name: " + newProjectName);
+    qDebug() << "Final project location: " + projectLocation;
+    qDebug() << "Original project name: " + projectName;
+    qDebug() << "New project name: " + newProjectName;
 
     QString mainQmlFilePath;
     QStringList importPaths;
 
-    printLog("Looking for qmlproject file in " + projectLocation);
+    qDebug() << "Looking for qmlproject file in " + projectLocation;
     const QString qmlProjectFile = findFile(projectLocation, newProjectName + ".qmlproject");
-    if (!qmlProjectFile.isEmpty())
-    {
-        printLog("Found qmlproject file: " + qmlProjectFile);
+    if (!qmlProjectFile.isEmpty()) {
+        qDebug() << "Found qmlproject file: " + qmlProjectFile;
         parseQmlprojectFile(qmlProjectFile, &mainQmlFilePath, &importPaths);
-    }
-    else
-    {
-        printWarn("Not found: \"*.qmlproject\". Looking for main.qml..");
+    } else {
+        qWarning() << "Not found: \"*.qmlproject\". Looking for main.qml..";
         mainQmlFilePath = findFile(projectLocation, "main.qml");
 
         if (mainQmlFilePath.isEmpty())
         {
-            printWarn("Not found: \"main.qml\". Looking for \"" + newProjectName + ".qml\"..");
+            qWarning() << "Not found: \"main.qml\". Looking for \"" + newProjectName + ".qml\"..";
             mainQmlFilePath = findFile(projectLocation, newProjectName + ".qml");
         }
     }
 
-    if (mainQmlFilePath.isEmpty())
-    {
-        printErr("No \"*.qmlproject\", \"main.qml\" or \"" + newProjectName + ".qml\" found in \"" + projectLocation + "\".");
+    if (mainQmlFilePath.isEmpty()) {
+        qCritical() << "No \"*.qmlproject\", \"main.qml\" or \"" + newProjectName
+                           + ".qml\" found in \"" + projectLocation + "\".";
         return false;
     }
 
-    printLog("Found mainQmlFile: " + mainQmlFilePath);
+    qDebug() << "Found mainQmlFile: " + mainQmlFilePath;
 
     QUrl mainQmlUrl = QUrl::fromUserInput(mainQmlFilePath);
     QFile file(mainQmlUrl.path().prepend(":"));
     if (!file.open(QIODevice::ReadOnly)) {
-        printErr("Could not open mainQmlfile for reading! " + file.fileName() + ": " + file.errorString());
+        qCritical() << "Could not open mainQmlfile for reading! " + file.fileName() + ": "
+                           + file.errorString();
         return false;
     }
 
-    printLog("Looking for qtquickcontrols2File in " + projectLocation);
+    qDebug() << "Looking for qtquickcontrols2File in " + projectLocation;
     const QString qtquickcontrols2File = findFile(projectLocation, "qtquickcontrols2.conf");
 
-    if (!qtquickcontrols2File.isEmpty())
-    {
-        printLog("Found qtquickcontrols2File: " + qtquickcontrols2File);
+    if (!qtquickcontrols2File.isEmpty()) {
+        qDebug() << "Found qtquickcontrols2File: " + qtquickcontrols2File;
         qputenv("QT_QUICK_CONTROLS_CONF", qtquickcontrols2File.toLatin1());
     }
 
-    printLog("Adding import paths");
-    for (const QString &importPath : importPaths)
-    {
-        printLog("-- Import path: " + importPath);
+    qDebug() << "Adding import paths";
+    for (const QString &importPath : importPaths) {
+        qDebug() << "-- Import path: " + importPath;
         m_qmlEngine.addImportPath(importPath);
     }
 
     QObject::connect(&m_qmlEngine,
                      &QQmlEngine::warnings,
                      this,
-                     [&](const QList<QQmlError> &warnings)
-                     {
-                         for (const auto &warning : warnings)
-                         {
-                             printWarn(warning.toString());
+                     [&](const QList<QQmlError> &warnings) {
+                         for (const auto &warning : warnings) {
+                             qWarning() << warning.toString();
                          }
                      });
 
-    printLog("Loading mainQmlUrl: " + mainQmlUrl.toString());
+    qDebug() << "Loading mainQmlUrl: " + mainQmlUrl.toString();
     m_qmlComponent.loadUrl(mainQmlUrl);
 
-    printLog("Waiting for qmlComponent to load");
+    qDebug() << "Waiting for qmlComponent to load";
     while (m_qmlComponent.isLoading())
         QCoreApplication::processEvents();
 
-    printLog("Checking if m_qmlComponent is ready");
-    if (!m_qmlComponent.isReady())
-    {
-        printErr("m_qmlComponent is not ready. Reason: " + m_qmlComponent.errorString());
+    qDebug() << "Checking if m_qmlComponent is ready";
+    if (!m_qmlComponent.isReady()) {
+        qCritical() << "m_qmlComponent is not ready. Reason: " + m_qmlComponent.errorString();
         return false;
     }
-    printLog("Creating top level object");
+    qDebug() << "Creating top level object";
     QObject *topLevel = m_qmlComponent.create();
-    if (!topLevel && m_qmlComponent.isError())
-    {
-        printErr("Error while creating Qml m_qmlComponent:" + m_qmlComponent.errorString());
+    if (!topLevel && m_qmlComponent.isError()) {
+        qCritical() << "Error while creating Qml m_qmlComponent:" + m_qmlComponent.errorString();
         return false;
     }
 
-    printLog("Setting up the quickWindow");
+    qDebug() << "Setting up the quickWindow";
     m_quickWindow.reset(qobject_cast<QQuickWindow *>(topLevel));
-    if (m_quickWindow)
-    {
-        printLog("Running with incubator controller");
+    if (m_quickWindow) {
+        qDebug() << "Running with incubator controller";
         m_qmlEngine.setIncubationController(m_quickWindow->incubationController());
-    }
-    else
-    {
-        printWarn("Top level object is not a QQuickWindow. Trying QQuickView...");
+    } else {
+        qWarning() << "Top level object is not a QQuickWindow. Trying QQuickView...";
 
         QQuickItem *contentItem = qobject_cast<QQuickItem *>(topLevel);
         if (!contentItem)
         {
-            printErr("Top level object cannot be casted to QQuickItem. Aborting.");
+            qCritical() << "Top level object cannot be casted to QQuickItem. Aborting.";
             return false;
         }
 
-        printLog("Initializing QQuickView");
+        qDebug() << "Initializing QQuickView";
         QQuickView *view = new QQuickView(&m_qmlEngine, nullptr);
         m_quickWindow.reset(view);
         view->setContent(mainQmlUrl, &m_qmlComponent, contentItem);
@@ -341,65 +319,44 @@ bool DesignViewer::runProject(const QByteArray &projectData, const QString &proj
     return true;
 }
 
-void DesignViewer::printLog(const QString &message)
-{
-    fprintf(stdout, "%s\n", qPrintable(message));
-}
-
-void DesignViewer::printWarn(const QString &message)
-{
-    fprintf(stderr, "WARNING:%s\n", qPrintable(message));
-}
-
-void DesignViewer::printError(const QString &message, const QString &fileName, int line)
-{
-    fprintf(stderr, "ERROR:%s\n", qPrintable(message));
-    QString escaped = message;
-    escaped.replace("'", "\'");
-    escaped.replace("\n", "\\n");
-    emscripten::val location = emscripten::val::global("window")["location"];
-    location.set("hash", std::string());
-    location.call<void>("reload");
-}
-
 void DesignViewer::showAppWindow()
 {
-    printLog("Resizing the QML app window");
+    qDebug() << "Resizing the QML app window";
     const QSize size;
 
-    printLog("Getting the QML app window container");
+    qDebug() << "Getting the QML app window container";
     emscripten::val qtContainer = emscripten::val::global("qtcontainer"); // global from index.html
-    printLog("Getting the QML app window style");
+    qDebug() << "Getting the QML app window style";
     emscripten::val qtContainerStyle = qtContainer["style"];
 
-    printLog("Setting the QML app window size");
+    qDebug() << "Setting the QML app window size";
     if (size.isEmpty()) {
-        printLog("Setting the QML app window size to 100%");
+        qDebug() << "Setting the QML app window size to 100%";
         qtContainerStyle.set("width", std::string("100%"));
         // qtContainerStyle.set("height",
         //                      std::string(
         //                          "100%")); // ### FIXME: 100% height gives 0px height for some reason
     } else {
-        printLog("Setting the QML app window size to "
-                 + QString("%1x%2").arg(size.width()).arg(size.height()));
+        qDebug() << "Setting the QML app window size to "
+                        + QString("%1x%2").arg(size.width()).arg(size.height());
         qtContainerStyle.set("width", QString("%1px").arg(size.width()).toStdString());
         qtContainerStyle.set("height", QString("%1px").arg(size.height()).toStdString());
     }
 
-    printLog("Setting the QML app window position");
+    qDebug() << "Setting the QML app window position";
 
     // Make Qt pick up the new container size by calling the resizeCanvasElement()
     // qtloader API. This needs to be done on delay after initial setup to make
     // sure qtloader is initialized.
     // QTimer::singleShot(0, [&]() {
-    //     emscripten::val instance = emscripten::val::global("instance");
+    //     emscripten::val instance = emscripten::val::global("instance";
     //     if (instance.isNull()) {
-    //         printErr("instance is null");
+    //         qCritical()<<"instance is null";
     //         return;
     //     }
     //     instance.call<void>("qtResizeContainerElement", qtContainer);
-    //     printLog("QML app window position set");
+    //     qDebug() << "QML app window position set";
     // });
-    printLog("Showing the QML app window");
+    qDebug() << "Showing the QML app window";
     m_quickWindow->show();
 }
diff --git a/src/designviewer.h b/src/designviewer.h
index 1736277c4455a90f5ca59341cb9b68f8769285b5..2dea2c2462f0c654d589f58db46243cea9d90db3 100644
--- a/src/designviewer.h
+++ b/src/designviewer.h
@@ -49,9 +49,6 @@ private:
 
     QWidget *m_appWindow = nullptr;
 
-    void printLog(const QString &message);
-    void printWarn(const QString &message);
-    void printError(const QString &message, const QString &fileName, int line);
     void showAppWindow();
 
     void fetchProject(QByteArray *data, QString *fileName);
diff --git a/src/main.cpp b/src/main.cpp
index d75d7d04951712d3700179f2a1e8f8dcf30227a6..541e4e20f3d89119f872876a005c957faf02e2ff 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -24,21 +24,59 @@
 ****************************************************************************/
 
 #include <QApplication>
-#include <QDebug>
-#include <QQmlContext>
 #include <QSurfaceFormat>
+#include <QtQuick3D/QQuick3D>
 
 #include "designviewer.h"
 
+void messageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg)
+{
+    QString logPrefix, logSuffix, newLog;
+    FILE *logFile = stdout;
+
+    QByteArray localMsg = msg.toLocal8Bit();
+    const char *file = context.file ? context.file : "";
+    const char *function = context.function ? context.function : "";
+
+    switch (type) {
+    case QtDebugMsg:
+        logPrefix = QStringLiteral("Debug: ");
+        break;
+    case QtInfoMsg:
+        logPrefix = QStringLiteral("Info: ");
+        break;
+    case QtWarningMsg:
+        logPrefix = QStringLiteral("Warning: ");
+        logFile = stderr;
+        break;
+    case QtCriticalMsg:
+        logPrefix = QStringLiteral("Critical: ");
+        logFile = stderr;
+        break;
+    case QtFatalMsg:
+        logPrefix = QStringLiteral("Fatal: ");
+        logSuffix = QStringLiteral(" (%1:%2, %3)").arg(file).arg(context.line).arg(function);
+        logFile = stderr;
+        break;
+    }
+
+    newLog += "(WASM) " + logPrefix + localMsg + logSuffix + "\n";
+    fprintf(logFile, "%s", newLog.toUtf8().constData());
+}
+
 int main(int argc, char *argv[])
 {
-    qDebug().noquote() << QString("Built on %1 %2\n").arg(__DATE__, __TIME__);
+    qInstallMessageHandler(messageHandler);
+    qDebug() << "Version: " << CMAKE_VAR_GIT_VERSION << ". Built on " << __DATE__ << __TIME__
+             << "with Qt" << QT_VERSION_STR;
 
     QSurfaceFormat format = QSurfaceFormat::defaultFormat();
     format.setVersion(3, 0);
+    format.setSamples(4);
     QSurfaceFormat::setDefaultFormat(format);
+    qDebug() << "Default format: " << format;
 
-    QCoreApplication::setApplicationVersion(QString("Built on %1 %2").arg(__DATE__, __TIME__));
+    QCoreApplication::setApplicationVersion(QStringLiteral(CMAKE_VAR_GIT_VERSION));
     QGuiApplication app(argc, argv);
     DesignViewer dv;
 
diff --git a/www/index.html b/www/index.html
index f1754b0c1a59d0d42587452250463223e4a609bd..87e83e18a9a4b8b0ebd4695790e4ce8f4de8b521 100644
--- a/www/index.html
+++ b/www/index.html
@@ -43,14 +43,14 @@
   <body onload="init()" class="qt-design-system">
     <figure style="overflow: visible" id="qtspinner">
       <center style="line-height: 150%">
-        <!-- <div class="c-box c-box--grey h-wysiwyg-html" data-scheme style="font-style: normal;"> 
+        <!-- <div class="c-box c-box--grey h-wysiwyg-html" data-scheme style="font-style: normal;">
           <p>Upcoming maintenance break on Tuesday 21st May</p>
-          <a class="c-link" target="_blank" rel="noopener noreferrer" 
+          <a class="c-link" target="_blank" rel="noopener noreferrer"
             href="https://forum.qt.io/topic/156671/upcoming-maintenance-break-on-the-qt-design-viewer-tuesday-21-05-2024">
             Learn more
           </a>
         </div> -->
-      
+
         <img
           src="resources/images/qtdesignstudioviewer-128.png"
           srcset="
@@ -64,7 +64,7 @@
           style="display: block"
         />
         <div id="title">Qt Design Viewer</div>
-        <div id="subtitle" class="subtitleclass">Powered by WebAssembly</div>
+        <div id="subtitle" class="subtitleclass"></div>
         <div id="qtstatus"></div>
         <noscript
           >JavaScript is disabled. Please enable JavaScript to use this
@@ -150,6 +150,9 @@
         and remains locally in Your browser, nothing gets uploaded into the
         cloud.
       </p>
+      <p>
+        You can report bugs or give feedback on <a href="https://bugreports.qt.io/secure/CreateIssueDetails!init.jspa?pid=11740&issuetype=1&components=24729&versions=20809">Qt Bug Reports.</a>
+      </p>
       <p>
         <a href="https://git.qt.io/design-studio/design-viewer/design-viewer-wasm"
           >"Qt Design Viewer" sources</a
diff --git a/www/scripts/script.js b/www/scripts/script.js
index 21c438bdc1fb6dcae08d7d445c634853930dbc0f..5ebe8163fb5aef0ac7a92209e71b6b1084ad3c84 100644
--- a/www/scripts/script.js
+++ b/www/scripts/script.js
@@ -64,6 +64,14 @@ window.addEventListener(
     false
 );
 
+function logError(error) {
+    console.error(error);
+    console.error(error.stack);
+    const status = document.querySelector('#qtstatus');
+    status.innerHTML = 'An error occurred while running the project.<br><br>Error Message:<br>' + error + ' <br><br>Please check the logs for more information.<br>Reloading in 10 seconds.';
+    setTimeout(() => location.reload(), 10000);
+}
+
 function handleFileSelection(event) {
     reader = new FileReader();
     var file = fileinput.files[0];
@@ -73,7 +81,12 @@ function handleFileSelection(event) {
         hideMainPage();
         loadProjector();
     };
-    reader.readAsArrayBuffer(file);
+
+    try {
+        reader.readAsArrayBuffer(file);
+    } catch (e) {
+        logError(e);
+    }
 }
 
 function loadFromServer(fileName, password) {
@@ -220,30 +233,38 @@ async function loadProjector() {
     }
 
     try {
-        showUi(spinner);
         status.innerHTML = 'Loading...';
         instance = await qtLoad({
             qt: {
                 onLoaded: () => {
+                    launchstatus.style.display = "none";
                     setContainerSize(container, window.innerWidth, window.innerHeight);
                     showUi(container);
                 },
                 onExit: exitData => {
-                    console.log("onExit");
+                    console.log("onExit: " + exitData.code + " " + exitData.text);
                     status.innerHTML = 'Application exit';
-                    status.innerHTML +=
-                        exitData.code !== undefined ? ` with code ` : '';
-                    status.innerHTML +=
-                        exitData.text !== undefined ? ` ()` : '';
-                    showUi(spinner);
+
+                    if (exitData.code === 0) {
+                        status.innerHTML += ' with success.';
+                        return;
+                    }
+
+                    status.innerHTML += ' with an error.';
+                    status.innerHTML += '<br><br>Exit code:<br>' + exitData.code;
+                    status.innerHTML += '<br><br>Exit message:<br>' + exitData.text;
+
+                    const reportLink = document.createElement('a');
+                    reportLink.href = 'https://bugreports.qt.io/secure/CreateIssueDetails!init.jspa?pid=11740&issuetype=1&components=24729&versions=20809&summary=Design+Viewer+Crash&description=' + encodeURIComponent('Exit code:\n' + exitData.code + '\n\nExit message:\n' + exitData.text);
+
+                    status.innerHTML += '<br><br>You can report this issue at <a href="' + reportLink.href + '">Qt Bug Reports.</a>';
                 },
                 entryFunction: window.createQtAppInstance,
                 containerElements: [container]
             }
         });
     } catch (e) {
-        console.error(e);
-        console.error(e.stack);
+        logError(e);
     }
 }