diff --git a/addons/website_slides/controllers/main.py b/addons/website_slides/controllers/main.py
index 85ea0ba9681372a0c4aea3ec72ada2c0ba2da326..718d01be640280ee3f873375fb931f9945eb15fe 100644
--- a/addons/website_slides/controllers/main.py
+++ b/addons/website_slides/controllers/main.py
@@ -61,6 +61,9 @@ class WebsiteSlides(WebsiteProfile):
         return True
 
     def _set_completed_slide(self, slide, quiz_attempts_inc=False):
+        # quiz use their specific mechanism to be marked as done
+        if slide.slide_type == 'quiz' or slide.question_ids:
+            raise werkzeug.exceptions.Forbidden(_("Slide with questions must be marked as done when submitting all good answers "))
         if slide.website_published and slide.channel_id.is_member:
             slide.action_set_completed(quiz_attempts_inc=quiz_attempts_inc)
         return True
@@ -662,6 +665,7 @@ class WebsiteSlides(WebsiteProfile):
         rank_progress = {}
         if not user_bad_answers:
             slide._action_set_quiz_done()
+            slide.action_set_completed(quiz_attempts_inc=True)
             lower_bound = request.env.user.rank_id.karma_min
             upper_bound = request.env.user.next_rank_id.karma_min
             rank_progress = {
@@ -674,11 +678,12 @@ class WebsiteSlides(WebsiteProfile):
         return {
             'goodAnswers': user_good_answers.ids,
             'badAnswers': user_bad_answers.ids,
-            'completed': not user_bad_answers,
+            'completed': slide.user_membership_id.sudo().completed,
+            'channel_completion': slide.channel_id.completion,
             'quizKarmaWon': quiz_info['quiz_karma_won'],
             'quizKarmaGain': quiz_info['quiz_karma_gain'],
             'quizAttemptsCount': quiz_info['quiz_attempts_count'],
-            'rankProgress': rank_progress
+            'rankProgress': rank_progress,
         }
 
     # --------------------------------------------------
diff --git a/addons/website_slides/static/src/js/slides_course_fullscreen_player.js b/addons/website_slides/static/src/js/slides_course_fullscreen_player.js
index a83df8a01cd59855f299bde126cd73375dc82e42..30d23f20f2fadb90064708eeb417d62de1e6d4cc 100644
--- a/addons/website_slides/static/src/js/slides_course_fullscreen_player.js
+++ b/addons/website_slides/static/src/js/slides_course_fullscreen_player.js
@@ -102,7 +102,7 @@ odoo.define('website_slides.fullscreen', function (require) {
                         if (totalTime && currentTime > totalTime - 30){
                             clearInterval(self.tid);
                             if (!self.slide.hasQuestion && !self.slide.completed){
-                                self.trigger_up('slide_completed', self.slide);
+                                self.trigger_up('slide_to_complete', self.slide);
                             }
                         }
                     }
@@ -289,8 +289,8 @@ odoo.define('website_slides.fullscreen', function (require) {
         },
         custom_events: {
             'change_slide': '_onChangeSlideRequest',
+            'slide_to_complete': '_onSlideToComplete',
             'slide_completed': '_onSlideCompleted',
-            'quiz_completed': '_onSlideCompleted',
             'slide_go_next': '_onSlideGoToNext',
         },
         /**
@@ -367,11 +367,17 @@ odoo.define('website_slides.fullscreen', function (require) {
         */
         _fetchSlideContent: function (){
             var slide = this.get('slide');
-            if (slide.type === 'webpage') {
+            if (slide.type === 'webpage' && !slide.isQuiz) {
                 return this._fetchHtmlContent();
             }
             return $.when();
         },
+        _markAsCompleted: function (slideId, completion) {
+            var slide = findSlide(this.slides, {id: slideId});
+            slide.completed = true;
+            this.sidebar.setSlideCompleted(slide.id);
+            this.sidebar.updateProgressbar(completion);
+        },
         /**
          * Extend the slide data list to add informations about rendering method, and other
          * specific values according to their slide_type.
@@ -459,9 +465,7 @@ odoo.define('website_slides.fullscreen', function (require) {
                         slide_id: slide.id,
                     }
                 }).then(function (data){
-                    slide.completed = true;
-                    self.sidebar.setSlideCompleted(slide.id);
-                    self.sidebar.updateProgressbar(data.channel_completion);
+                    self._markAsCompleted(slideId, data.channel_completion);
                 });
             }
             return $.when();
@@ -504,13 +508,23 @@ odoo.define('website_slides.fullscreen', function (require) {
             });
             this.set('slide', newSlide);
         },
+        /**
+         * Triggered when subwidget has mark the slide as done, and the UI need to be adapted.
+         *
+         * @private
+         */
+        _onSlideCompleted: function (ev) {
+            var slide = ev.data.slide;
+            var completion = ev.data.completion;
+            this._markAsCompleted(slide.id, completion);
+        },
         /**
          * Triggered when sub widget business is done and that slide
          * can now be marked as done.
          *
          * @private
          */
-        _onSlideCompleted: function (ev) {
+        _onSlideToComplete: function (ev) {
             if (!session.is_website_user) {  // no useless RPC call
                 var slideId = ev.data.id;
                 this._setCompleted(slideId);
diff --git a/addons/website_slides/static/src/js/slides_course_quiz.js b/addons/website_slides/static/src/js/slides_course_quiz.js
index c969e38623bd244cbd272a3c1cf7a6a47f804cc3..9e2b9b7ece50081cf4ea767fc9b9236abc96add2 100644
--- a/addons/website_slides/static/src/js/slides_course_quiz.js
+++ b/addons/website_slides/static/src/js/slides_course_quiz.js
@@ -177,15 +177,6 @@ odoo.define('website_slides.quiz', function (require) {
                 QWeb.render('slide.slide.quiz.validation', {'widget': this})
             );
         },
-
-        /**
-         * Set the slide as completed and done. Trigger up the completion.
-         *
-         * @param {Integer} completion
-         */
-        _setCompleted: function () {
-            this.trigger_up('quiz_completed', this.slide);
-        },
         /*
          * Submit the given answer, and display the result
          *
@@ -203,13 +194,12 @@ odoo.define('website_slides.quiz', function (require) {
                 if (data.error) {
                     self._alertShow(data.error);
                 } else {
-                    self.slide.completed = data.completed;
                     self.quiz = _.extend(self.quiz, data);
                     self._renderAnswersHighlighting();
                     self._renderValidationInfo();
-                    if (self.slide.completed) {
+                    if (data.completed) {
                         self._renderSuccessModal(data);
-                        self._setCompleted();
+                        self.trigger_up('slide_completed', {slide: self.slide, completion: data.channel_completion});
                     }
                 }
             });
@@ -266,10 +256,10 @@ odoo.define('website_slides.quiz', function (require) {
     });
 
     sAnimations.registry.websiteSlidesQuizNoFullscreen = sAnimations.Class.extend({
-        selector: '.o_wslides_js_lesson_quiz',
+        selector: '.o_wslides_lesson_main', // selector of complete page, as we need slide content and aside content table
         custom_events: {
             slide_go_next: '_onQuizNextSlide',
-            quiz_completed: '_onQuizCompleted',
+            slide_completed: '_onQuizCompleted',
         },
 
         //----------------------------------------------------------------------
@@ -282,8 +272,9 @@ odoo.define('website_slides.quiz', function (require) {
          */
         start: function () {
             var self = this;
+            this.quizWidgets = [];
             var defs = [this._super.apply(this, arguments)];
-            $('.o_wslides_js_lesson_quiz').each(function () {
+            this.$('.o_wslides_js_lesson_quiz').each(function () {
                 var slideData = $(this).data();
                 slideData.quizData = {
                     questions: self._extractQuestionsAndAnswers(),
@@ -300,13 +291,17 @@ odoo.define('website_slides.quiz', function (require) {
         //----------------------------------------------------------------------
         // Handlers
         //---------------------------------------------------------------------
-
-        _onQuizCompleted: function (slideId) {
-            console.log('set completed', slideId);
+        _onQuizCompleted: function (ev) {
+            var self = this;
+            var slide = ev.data.slide;
+            var completion = ev.data.completion;
+            this.$('#o_wslides_lesson_aside_slide_check_' + slide.id).addClass('text-success fa-check-circle').removeClass('text-600 fa-circle-o');
+            // need to use global selector as progress bar is ouside this animation widget scope
+            $('.o_wslides_lesson_header .progress-bar').css('width', completion + "%");
+            $('.o_wslides_lesson_header .progress span').text(_.str.sprintf("%s %%", completion));
         },
-
         _onQuizNextSlide: function () {
-            var url = this.$el.data('next-slide-url');
+            var url = this.$('.o_wslides_js_lesson_quiz').data('next-slide-url');
             window.location.replace(url);
         },
 
diff --git a/addons/website_slides_survey/controllers/slides.py b/addons/website_slides_survey/controllers/slides.py
index 9396de502b8da4e7348e07575734c2f48f2efa0b..a7dad0b175d108ef828e4d33a1056cde48f54239 100644
--- a/addons/website_slides_survey/controllers/slides.py
+++ b/addons/website_slides_survey/controllers/slides.py
@@ -1,8 +1,10 @@
 # -*- coding: utf-8 -*-
 # Part of Odoo. See LICENSE file for full copyright and licensing details.
 
-from odoo.addons.website_slides.controllers.main import WebsiteSlides
+import werkzeug
 
+from odoo.addons.website_slides.controllers.main import WebsiteSlides
+from odoo import _
 from odoo.http import request
 
 
@@ -49,6 +51,13 @@ class WebsiteSlides(WebsiteSlides):
 
         return result
 
+    # Utils
+    # ---------------------------------------------------
+    def _set_completed_slide(self, slide, quiz_attempts_inc=False):
+        if slide.slide_type == 'certification':
+            raise werkzeug.exceptions.Forbidden(_("Certification slides are completed when the survey is succeeded."))
+        return super(WebsiteSlides, self)._set_completed_slide(slide, quiz_attempts_inc=quiz_attempts_inc)
+
     # Profile
     # ---------------------------------------------------
     def _prepare_user_slides_profile(self, user):