diff --git a/addons/website/static/src/snippets/s_dynamic_snippet/000.js b/addons/website/static/src/snippets/s_dynamic_snippet/000.js
index 71b551738b5d39f1daca92ed5466d9f54db6755b..d6a3e0ffca4044b11803828eaf2d07faf707db2c 100644
--- a/addons/website/static/src/snippets/s_dynamic_snippet/000.js
+++ b/addons/website/static/src/snippets/s_dynamic_snippet/000.js
@@ -125,6 +125,13 @@ const DynamicSnippet = publicWidget.Widget.extend({
             });
         }
     },
+    /**
+     *
+     * @private
+     */
+    _mustMessageWarningBeHidden: function() {
+        return this._isConfigComplete() || !this.editableMode;
+    },
     /**
      *
      * @private
@@ -132,7 +139,7 @@ const DynamicSnippet = publicWidget.Widget.extend({
     _manageWarningMessageVisibility: async function () {
         this.$el.find('.missing_option_warning').toggleClass(
             'd-none',
-            this._isConfigComplete()
+            this._mustMessageWarningBeHidden()
         );
     },
     /**
diff --git a/addons/website_sale/static/src/snippets/s_dynamic_snippet_products/000.js b/addons/website_sale/static/src/snippets/s_dynamic_snippet_products/000.js
index 3763593f98f57719d640a32d959e294b77442b04..2bd132848765d5fddadd384b41fe2d0c4717a700 100644
--- a/addons/website_sale/static/src/snippets/s_dynamic_snippet_products/000.js
+++ b/addons/website_sale/static/src/snippets/s_dynamic_snippet_products/000.js
@@ -22,6 +22,20 @@ const DynamicSnippetProducts = DynamicSnippetCarousel.extend({
     _isConfigComplete: function () {
         return this._super.apply(this, arguments) && this.$el.get(0).dataset.productCategoryId !== undefined;
     },
+    /**
+     *
+     * @override
+     * @private
+     */
+    _mustMessageWarningBeHidden: function() {
+        const isInitialDrop = this.$el.get(0).dataset.templateKey === undefined;
+        // This snippet has default values obtained after the initial start and render after drop.
+        // Because of this there is an initial refresh happening right after.
+        // We want to avoid showing the incomplete config message before this refresh.
+        // Since the refreshed call will always happen with a defined templateKey,
+        // if it is not set yet, we know it is the drop call and we can avoid showing the message.
+        return isInitialDrop || this._super.apply(this, arguments);
+    },
     /**
      * Method to be overridden in child components in order to provide a search
      * domain if needed.
@@ -30,7 +44,10 @@ const DynamicSnippetProducts = DynamicSnippetCarousel.extend({
      */
     _getSearchDomain: function () {
         const searchDomain = this._super.apply(this, arguments);
-        searchDomain.push(['public_categ_ids', 'child_of', parseInt(this.$el.get(0).dataset.productCategoryId)]);
+        const productCategoryId = parseInt(this.$el.get(0).dataset.productCategoryId);
+        if (productCategoryId >= 0) {
+            searchDomain.push(['public_categ_ids', 'child_of', productCategoryId]);
+        }
         return searchDomain;
     },
 
diff --git a/addons/website_sale/static/src/snippets/s_dynamic_snippet_products/options.js b/addons/website_sale/static/src/snippets/s_dynamic_snippet_products/options.js
index f059e78a8618b5770dad5ed3b2880b7ac0f0620f..3dabb014f21e8d0c9795ac1441ab17439c08ea7e 100644
--- a/addons/website_sale/static/src/snippets/s_dynamic_snippet_products/options.js
+++ b/addons/website_sale/static/src/snippets/s_dynamic_snippet_products/options.js
@@ -26,6 +26,8 @@ const dynamicSnippetProductsOptions = s_dynamic_snippet_carousel_options.extend(
             if (data.length) {
                 this.$target.get(0).dataset.filterId = data[0].id;
                 this.$target.get(0).dataset.numberOfRecords = this.dynamicFilters[data[0].id].limit;
+                this._refreshPublicWidgets();
+                // Refresh is needed because default values are obtained after start()
             }
         });
     },
@@ -82,6 +84,22 @@ const dynamicSnippetProductsOptions = s_dynamic_snippet_carousel_options.extend(
         const productCategoriesSelectorEl = uiFragment.querySelector('[data-name="product_category_opt"]');
         return this._renderSelectUserValueWidgetButtons(productCategoriesSelectorEl, this.productCategories);
     },
+    /**
+     * Sets default options values.
+     * @override
+     * @private
+     */
+    _setOptionsDefaultValues: function () {
+        this._super.apply(this, arguments);
+        const templateKeys = this.$el.find("we-select[data-attribute-name='templateKey'] we-selection-items we-button");
+        if (templateKeys.length > 0) {
+            this._setOptionValue('templateKey', templateKeys.attr('data-select-data-attribute'));
+        }
+        const productCategories = this.$el.find("we-select[data-attribute-name='productCategoryId'] we-selection-items we-button");
+        if (productCategories.length > 0) {
+            this._setOptionValue('productCategoryId', productCategories.attr('data-select-data-attribute'));
+        }
+    },
 
 });
 
diff --git a/addons/website_sale/views/snippets/s_dynamic_snippet_products.xml b/addons/website_sale/views/snippets/s_dynamic_snippet_products.xml
index 9b2c18a9a6911b48b2a04754df78a211fbc216a1..2e871086a5d0f128a034a2c83ca2bdd145e8d15a 100644
--- a/addons/website_sale/views/snippets/s_dynamic_snippet_products.xml
+++ b/addons/website_sale/views/snippets/s_dynamic_snippet_products.xml
@@ -11,6 +11,7 @@
                 <t t-set="snippet_name" t-value="'dynamic_snippet_products'"/>
                 <t t-set="snippet_selector" t-value="'.s_dynamic_snippet_products'"/>
                 <we-select string="Product Category" data-name="product_category_opt" data-attribute-name="productCategoryId" data-no-preview="true">
+                    <we-button data-select-data-attribute="-1">All Products</we-button>
                 </we-select>
             </t>
         </xpath>