diff --git a/bt5/erp5_web_js_style/RegisteredSkinSelectionTemplateItem/registered_skin_selection.xml b/bt5/erp5_web_js_style/RegisteredSkinSelectionTemplateItem/registered_skin_selection.xml
new file mode 100644
index 0000000000000000000000000000000000000000..45ab52d0fb71b7ec586a23ed5067a740c037be04
--- /dev/null
+++ b/bt5/erp5_web_js_style/RegisteredSkinSelectionTemplateItem/registered_skin_selection.xml
@@ -0,0 +1,10 @@
+<registered_skin_selection>
+ <skin_folder_selection>
+  <skin_folder>erp5_web_js_style_ui</skin_folder>
+  <skin_selection>Jsstyle</skin_selection>
+ </skin_folder_selection>
+ <skin_folder_selection>
+  <skin_folder>erp5_xhtml_style</skin_folder>
+  <skin_selection>Jsstyle</skin_selection>
+ </skin_folder_selection>
+</registered_skin_selection>
\ No newline at end of file
diff --git a/bt5/erp5_web_js_style/SkinTemplateItem/portal_skins/erp5_web_js_style.xml b/bt5/erp5_web_js_style/SkinTemplateItem/portal_skins/erp5_web_js_style.xml
new file mode 100644
index 0000000000000000000000000000000000000000..2c61fa643987bcdc0aec94418c814d1baf2d4e6f
--- /dev/null
+++ b/bt5/erp5_web_js_style/SkinTemplateItem/portal_skins/erp5_web_js_style.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0"?>
+<ZopeData>
+  <record id="1" aka="AAAAAAAAAAE=">
+    <pickle>
+      <global name="Folder" module="OFS.Folder"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>_objects</string> </key>
+            <value>
+              <tuple/>
+            </value>
+        </item>
+        <item>
+            <key> <string>id</string> </key>
+            <value> <string>erp5_web_js_style</string> </value>
+        </item>
+        <item>
+            <key> <string>title</string> </key>
+            <value> <string></string> </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+</ZopeData>
diff --git a/bt5/erp5_web_js_style/SkinTemplateItem/portal_skins/erp5_web_js_style/WebSection_viewJsstylePreference.xml b/bt5/erp5_web_js_style/SkinTemplateItem/portal_skins/erp5_web_js_style/WebSection_viewJsstylePreference.xml
new file mode 100644
index 0000000000000000000000000000000000000000..80caa9e3d33db07a0ac650f362ea4324df07a345
--- /dev/null
+++ b/bt5/erp5_web_js_style/SkinTemplateItem/portal_skins/erp5_web_js_style/WebSection_viewJsstylePreference.xml
@@ -0,0 +1,138 @@
+<?xml version="1.0"?>
+<ZopeData>
+  <record id="1" aka="AAAAAAAAAAE=">
+    <pickle>
+      <global name="ERP5 Form" module="erp5.portal_type"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>_bind_names</string> </key>
+            <value>
+              <object>
+                <klass>
+                  <global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
+                </klass>
+                <tuple/>
+                <state>
+                  <dictionary>
+                    <item>
+                        <key> <string>_asgns</string> </key>
+                        <value>
+                          <dictionary/>
+                        </value>
+                    </item>
+                  </dictionary>
+                </state>
+              </object>
+            </value>
+        </item>
+        <item>
+            <key> <string>_objects</string> </key>
+            <value>
+              <tuple/>
+            </value>
+        </item>
+        <item>
+            <key> <string>action</string> </key>
+            <value> <string>Base_edit</string> </value>
+        </item>
+        <item>
+            <key> <string>description</string> </key>
+            <value> <string></string> </value>
+        </item>
+        <item>
+            <key> <string>edit_order</string> </key>
+            <value>
+              <list/>
+            </value>
+        </item>
+        <item>
+            <key> <string>encoding</string> </key>
+            <value> <string>UTF-8</string> </value>
+        </item>
+        <item>
+            <key> <string>enctype</string> </key>
+            <value> <string>multipart/form-data</string> </value>
+        </item>
+        <item>
+            <key> <string>group_list</string> </key>
+            <value>
+              <list>
+                <string>left</string>
+                <string>right</string>
+                <string>center</string>
+              </list>
+            </value>
+        </item>
+        <item>
+            <key> <string>groups</string> </key>
+            <value>
+              <dictionary>
+                <item>
+                    <key> <string>center</string> </key>
+                    <value>
+                      <list/>
+                    </value>
+                </item>
+                <item>
+                    <key> <string>left</string> </key>
+                    <value>
+                      <list>
+                        <string>my_configuration_style_gadget_url</string>
+                      </list>
+                    </value>
+                </item>
+                <item>
+                    <key> <string>right</string> </key>
+                    <value>
+                      <list/>
+                    </value>
+                </item>
+              </dictionary>
+            </value>
+        </item>
+        <item>
+            <key> <string>id</string> </key>
+            <value> <string>WebSection_viewJsstylePreference</string> </value>
+        </item>
+        <item>
+            <key> <string>method</string> </key>
+            <value> <string>POST</string> </value>
+        </item>
+        <item>
+            <key> <string>name</string> </key>
+            <value> <string>WebSection_viewHateoasPreference</string> </value>
+        </item>
+        <item>
+            <key> <string>pt</string> </key>
+            <value> <string>form_view</string> </value>
+        </item>
+        <item>
+            <key> <string>row_length</string> </key>
+            <value> <int>4</int> </value>
+        </item>
+        <item>
+            <key> <string>stored_encoding</string> </key>
+            <value> <string>UTF-8</string> </value>
+        </item>
+        <item>
+            <key> <string>title</string> </key>
+            <value> <string>Web Section Preference</string> </value>
+        </item>
+        <item>
+            <key> <string>unicode_mode</string> </key>
+            <value> <int>0</int> </value>
+        </item>
+        <item>
+            <key> <string>update_action</string> </key>
+            <value> <string></string> </value>
+        </item>
+        <item>
+            <key> <string>update_action_title</string> </key>
+            <value> <string></string> </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+</ZopeData>
diff --git a/bt5/erp5_web_js_style/SkinTemplateItem/portal_skins/erp5_web_js_style/WebSection_viewJsstylePreference/my_configuration_style_gadget_url.xml b/bt5/erp5_web_js_style/SkinTemplateItem/portal_skins/erp5_web_js_style/WebSection_viewJsstylePreference/my_configuration_style_gadget_url.xml
new file mode 100644
index 0000000000000000000000000000000000000000..58eac9b947c7230dadf27a59b97cde33071f851d
--- /dev/null
+++ b/bt5/erp5_web_js_style/SkinTemplateItem/portal_skins/erp5_web_js_style/WebSection_viewJsstylePreference/my_configuration_style_gadget_url.xml
@@ -0,0 +1,96 @@
+<?xml version="1.0"?>
+<ZopeData>
+  <record id="1" aka="AAAAAAAAAAE=">
+    <pickle>
+      <global name="ProxyField" module="Products.ERP5Form.ProxyField"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>delegated_list</string> </key>
+            <value>
+              <list>
+                <string>title</string>
+              </list>
+            </value>
+        </item>
+        <item>
+            <key> <string>id</string> </key>
+            <value> <string>my_configuration_style_gadget_url</string> </value>
+        </item>
+        <item>
+            <key> <string>message_values</string> </key>
+            <value>
+              <dictionary>
+                <item>
+                    <key> <string>external_validator_failed</string> </key>
+                    <value> <string>The input failed the external validator.</string> </value>
+                </item>
+              </dictionary>
+            </value>
+        </item>
+        <item>
+            <key> <string>overrides</string> </key>
+            <value>
+              <dictionary>
+                <item>
+                    <key> <string>field_id</string> </key>
+                    <value> <string></string> </value>
+                </item>
+                <item>
+                    <key> <string>form_id</string> </key>
+                    <value> <string></string> </value>
+                </item>
+                <item>
+                    <key> <string>target</string> </key>
+                    <value> <string></string> </value>
+                </item>
+              </dictionary>
+            </value>
+        </item>
+        <item>
+            <key> <string>tales</string> </key>
+            <value>
+              <dictionary>
+                <item>
+                    <key> <string>field_id</string> </key>
+                    <value> <string></string> </value>
+                </item>
+                <item>
+                    <key> <string>form_id</string> </key>
+                    <value> <string></string> </value>
+                </item>
+                <item>
+                    <key> <string>target</string> </key>
+                    <value> <string></string> </value>
+                </item>
+              </dictionary>
+            </value>
+        </item>
+        <item>
+            <key> <string>values</string> </key>
+            <value>
+              <dictionary>
+                <item>
+                    <key> <string>field_id</string> </key>
+                    <value> <string>my_view_mode_reference</string> </value>
+                </item>
+                <item>
+                    <key> <string>form_id</string> </key>
+                    <value> <string>Base_viewFieldLibrary</string> </value>
+                </item>
+                <item>
+                    <key> <string>target</string> </key>
+                    <value> <string>Click to edit the target</string> </value>
+                </item>
+                <item>
+                    <key> <string>title</string> </key>
+                    <value> <string>Style Gadget URL</string> </value>
+                </item>
+              </dictionary>
+            </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+</ZopeData>
diff --git a/bt5/erp5_web_js_style/SkinTemplateItem/portal_skins/erp5_web_js_style_ui.xml b/bt5/erp5_web_js_style/SkinTemplateItem/portal_skins/erp5_web_js_style_ui.xml
new file mode 100644
index 0000000000000000000000000000000000000000..a0e3586b96f8ebe0017838c4479b8be795288d3f
--- /dev/null
+++ b/bt5/erp5_web_js_style/SkinTemplateItem/portal_skins/erp5_web_js_style_ui.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0"?>
+<ZopeData>
+  <record id="1" aka="AAAAAAAAAAE=">
+    <pickle>
+      <global name="Folder" module="OFS.Folder"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>_local_properties</string> </key>
+            <value>
+              <tuple>
+                <dictionary>
+                  <item>
+                      <key> <string>id</string> </key>
+                      <value> <string>business_template_skin_layer_priority</string> </value>
+                  </item>
+                  <item>
+                      <key> <string>type</string> </key>
+                      <value> <string>float</string> </value>
+                  </item>
+                </dictionary>
+              </tuple>
+            </value>
+        </item>
+        <item>
+            <key> <string>_objects</string> </key>
+            <value>
+              <tuple/>
+            </value>
+        </item>
+        <item>
+            <key> <string>business_template_skin_layer_priority</string> </key>
+            <value> <float>99.0</float> </value>
+        </item>
+        <item>
+            <key> <string>id</string> </key>
+            <value> <string>erp5_web_js_style_ui</string> </value>
+        </item>
+        <item>
+            <key> <string>title</string> </key>
+            <value> <string></string> </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+</ZopeData>
diff --git a/bt5/erp5_web_js_style/SkinTemplateItem/portal_skins/erp5_web_js_style_ui/WebSite_generateNavigationHTML.py b/bt5/erp5_web_js_style/SkinTemplateItem/portal_skins/erp5_web_js_style_ui/WebSite_generateNavigationHTML.py
new file mode 100644
index 0000000000000000000000000000000000000000..f3b707ed68c4aa8600143a1046bc41b07ac4c0fd
--- /dev/null
+++ b/bt5/erp5_web_js_style/SkinTemplateItem/portal_skins/erp5_web_js_style_ui/WebSite_generateNavigationHTML.py
@@ -0,0 +1,50 @@
+import cgi
+import re
+
+web_site = context
+
+def _(string_to_escape):
+  return cgi.escape("%s" % string_to_escape, quote=False)
+
+
+def __(string_to_escape):
+  return cgi.escape("%s" % string_to_escape, quote=True)
+
+
+def generateSectionListHTML(result_list, section_list):
+  if (section_list):
+    result_list.append('<ul>')
+    for section in section_list:
+      result_list.append('<li><a href="%s">%s</a>' % (_(section['url']), __(section['translated_title'])))
+      generateSectionListHTML(result_list, section['subsection'])
+      result_list.append('</li>')
+    result_list.append('</ul>')
+
+
+# Language
+result_list = ['<nav id="language"><ul>']
+
+available_language_set = web_site.getLayoutProperty("available_language_set", default=['en'])
+default_language = web_site.getLayoutProperty("default_available_language", default='en')
+website_url_set = {}
+root_website_url = web_site.getOriginalDocument().absolute_url()
+website_url_pattern = r'^%s(?:%s)*(/|$)' % (
+  re.escape(root_website_url),
+  '|'.join('/' + re.escape(x) for x in available_language_set))
+for language in available_language_set:
+  if language == default_language:
+    website_url_set[language] = re.sub(website_url_pattern, r'%s/\1' % root_website_url, web_site.absolute_url())
+  else:
+    website_url_set[language] = re.sub(website_url_pattern, r'%s/%s/\1' % (root_website_url, language), web_site.absolute_url())
+
+for language, url in website_url_set.items():
+  result_list += '<li><a href="%s" hreflang="%s"><abbr lang="%s">%s</abbr></a></li>' % (__(url), _(language), _(language), __(language))
+result_list.append('</ul></nav>')
+
+# Sitemap
+result_list.append('<nav id="sitemap">')
+result_list.append('<a href="%s">%s</a>' % (_(web_site.absolute_url()), __(web_site.getTranslatedTitle())))
+generateSectionListHTML(result_list, web_site.WebSection_getSiteMapTree(depth=99, include_subsection=1))
+result_list.append('</nav>')
+
+return ''.join(result_list)
diff --git a/bt5/erp5_web_js_style/SkinTemplateItem/portal_skins/erp5_web_js_style_ui/WebSite_generateNavigationHTML.xml b/bt5/erp5_web_js_style/SkinTemplateItem/portal_skins/erp5_web_js_style_ui/WebSite_generateNavigationHTML.xml
new file mode 100644
index 0000000000000000000000000000000000000000..30661ec1875067fcc9c74d25b38d03040c118434
--- /dev/null
+++ b/bt5/erp5_web_js_style/SkinTemplateItem/portal_skins/erp5_web_js_style_ui/WebSite_generateNavigationHTML.xml
@@ -0,0 +1,62 @@
+<?xml version="1.0"?>
+<ZopeData>
+  <record id="1" aka="AAAAAAAAAAE=">
+    <pickle>
+      <global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>Script_magic</string> </key>
+            <value> <int>3</int> </value>
+        </item>
+        <item>
+            <key> <string>_bind_names</string> </key>
+            <value>
+              <object>
+                <klass>
+                  <global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
+                </klass>
+                <tuple/>
+                <state>
+                  <dictionary>
+                    <item>
+                        <key> <string>_asgns</string> </key>
+                        <value>
+                          <dictionary>
+                            <item>
+                                <key> <string>name_container</string> </key>
+                                <value> <string>container</string> </value>
+                            </item>
+                            <item>
+                                <key> <string>name_context</string> </key>
+                                <value> <string>context</string> </value>
+                            </item>
+                            <item>
+                                <key> <string>name_m_self</string> </key>
+                                <value> <string>script</string> </value>
+                            </item>
+                            <item>
+                                <key> <string>name_subpath</string> </key>
+                                <value> <string>traverse_subpath</string> </value>
+                            </item>
+                          </dictionary>
+                        </value>
+                    </item>
+                  </dictionary>
+                </state>
+              </object>
+            </value>
+        </item>
+        <item>
+            <key> <string>_params</string> </key>
+            <value> <string></string> </value>
+        </item>
+        <item>
+            <key> <string>id</string> </key>
+            <value> <string>WebSite_generateNavigationHTML</string> </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+</ZopeData>
diff --git a/bt5/erp5_web_js_style/SkinTemplateItem/portal_skins/erp5_web_js_style_ui/jsstyle.css.css b/bt5/erp5_web_js_style/SkinTemplateItem/portal_skins/erp5_web_js_style_ui/jsstyle.css.css
new file mode 100644
index 0000000000000000000000000000000000000000..2c66cd54901136e679501e78bd992f77fe2149c5
--- /dev/null
+++ b/bt5/erp5_web_js_style/SkinTemplateItem/portal_skins/erp5_web_js_style_ui/jsstyle.css.css
@@ -0,0 +1,75 @@
+body {
+  display: grid;
+  grid-template-raws: repeat(3, 1fr);
+}
+body > nav#sitemap {
+  grid-row: 1;
+  background-color: #DDD;
+  display: flex;
+  flex-wrap: wrap;
+  justify-content: space-between;
+  min-height: 2.5em;
+  align-items: center;
+}
+body > nav#sitemap > a {
+  padding-left: 1em;
+  padding-right: 1em;
+}
+body > nav#sitemap ul {
+  margin: 0;
+}
+body > nav#sitemap ul,
+body > nav#sitemap li,
+body > nav#sitemap a {
+  padding: 0;
+  display: flex;
+  flex: 1;
+}
+body > nav#sitemap ul:not(:first-child),
+body > nav#sitemap li:not(:first-child),
+body > nav#sitemap a:not(:first-child) {
+  padding: 0 1em;
+}
+body main {
+  grid-row: 2;
+}
+body main fieldset {
+  border: none;
+}
+body main fieldset > div {
+  display: flex;
+  flex-flow: row nowrap;
+}
+body main fieldset > div > label {
+  margin-right: 1em;
+  font-weight: bold;
+  min-width: 10%;
+}
+body > nav#language {
+  grid-row: 3;
+  background-color: #DDD;
+  display: flex;
+  flex-wrap: wrap;
+  justify-content: space-between;
+  min-height: 2.5em;
+  align-items: center;
+}
+body > nav#language > a {
+  padding-left: 1em;
+  padding-right: 1em;
+}
+body > nav#language ul {
+  margin: 0;
+}
+body > nav#language ul,
+body > nav#language li,
+body > nav#language a {
+  padding: 0;
+  display: flex;
+  flex: 1;
+}
+body > nav#language ul:not(:first-child),
+body > nav#language li:not(:first-child),
+body > nav#language a:not(:first-child) {
+  padding: 0 1em;
+}
diff --git a/bt5/erp5_web_js_style/SkinTemplateItem/portal_skins/erp5_web_js_style_ui/jsstyle.css.xml b/bt5/erp5_web_js_style/SkinTemplateItem/portal_skins/erp5_web_js_style_ui/jsstyle.css.xml
new file mode 100644
index 0000000000000000000000000000000000000000..596814c0794a0fc839dc770e53f236ac649acc88
--- /dev/null
+++ b/bt5/erp5_web_js_style/SkinTemplateItem/portal_skins/erp5_web_js_style_ui/jsstyle.css.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0"?>
+<ZopeData>
+  <record id="1" aka="AAAAAAAAAAE=">
+    <pickle>
+      <global name="File" module="OFS.Image"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>_Cacheable__manager_id</string> </key>
+            <value> <string>http_cache</string> </value>
+        </item>
+        <item>
+            <key> <string>__name__</string> </key>
+            <value> <string>jsstyle.css</string> </value>
+        </item>
+        <item>
+            <key> <string>content_type</string> </key>
+            <value> <string>text/css</string> </value>
+        </item>
+        <item>
+            <key> <string>precondition</string> </key>
+            <value> <string></string> </value>
+        </item>
+        <item>
+            <key> <string>title</string> </key>
+            <value> <string></string> </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+</ZopeData>
diff --git a/bt5/erp5_web_js_style/SkinTemplateItem/portal_skins/erp5_web_js_style_ui/jsstyle.js.js b/bt5/erp5_web_js_style/SkinTemplateItem/portal_skins/erp5_web_js_style_ui/jsstyle.js.js
new file mode 100644
index 0000000000000000000000000000000000000000..b36096544516b974f3f7cf558cdd2602d8ed9deb
--- /dev/null
+++ b/bt5/erp5_web_js_style/SkinTemplateItem/portal_skins/erp5_web_js_style_ui/jsstyle.js.js
@@ -0,0 +1,208 @@
+/*globals window, document, RSVP, rJS, XMLHttpRequest, DOMParser, URL,
+          loopEventListener, history */
+/*jslint indent: 2, maxlen: 80*/
+(function (window, document, RSVP, rJS, XMLHttpRequest, DOMParser, URL,
+          loopEventListener, history) {
+  "use strict";
+
+  // XXX Copy/paste from renderjs
+  function ajax(url) {
+    var xhr;
+    function resolver(resolve, reject) {
+      function handler() {
+        try {
+          if (xhr.readyState === 0) {
+            // UNSENT
+            reject(xhr);
+          } else if (xhr.readyState === 4) {
+            // DONE
+            if ((xhr.status < 200) || (xhr.status >= 300) ||
+                (!/^text\/html[;]?/.test(
+                  xhr.getResponseHeader("Content-Type") || ""
+                ))) {
+              reject(xhr);
+            } else {
+              resolve(xhr);
+            }
+          }
+        } catch (e) {
+          reject(e);
+        }
+      }
+
+      xhr = new XMLHttpRequest();
+      xhr.open("GET", url);
+      xhr.onreadystatechange = handler;
+      xhr.setRequestHeader('Accept', 'text/html');
+      xhr.withCredentials = true;
+      xhr.send();
+    }
+    function canceller() {
+      if ((xhr !== undefined) && (xhr.readyState !== xhr.DONE)) {
+        xhr.abort();
+      }
+    }
+    return new RSVP.Promise(resolver, canceller);
+  }
+
+  function removeHash(url) {
+    var index = url.indexOf('#');
+    if (index > 0) {
+      url = url.substring(0, index);
+    }
+    return url;
+  }
+
+  function scrollToHash(hash) {
+    var scroll_element = null;
+
+    if (hash) {
+      hash = hash.split('#', 2)[1];
+      if (hash === undefined) {
+        hash = "";
+      }
+      if (hash) {
+        scroll_element = document.querySelector(hash);
+      }
+    }
+
+    if (scroll_element === null) {
+      window.scrollTo(0, 0);
+    } else {
+      scroll_element.scrollIntoView(true);
+    }
+
+  }
+
+  function renderPage(gadget, page_url, hash) {
+    return new RSVP.Queue(RSVP.hash({
+      xhr: ajax(page_url),
+      style_gadget: gadget.getDeclaredGadget('renderer')
+    }))
+      .push(function (result_dict) {
+        var dom_parser = (new DOMParser()).parseFromString(
+          result_dict.xhr.responseText,
+          'text/html'
+        );
+        document.title = dom_parser.title;
+        return result_dict.style_gadget.render(
+          dom_parser.body.querySelector('main').innerHTML
+        );
+      })
+      .push(function () {
+        return scrollToHash(hash);
+      });
+  }
+
+  function listenURLChange() {
+    var gadget = this;
+
+    // prevent automatic page location restoration
+    if (history.scrollRestoration) {
+      history.scrollRestoration = 'manual';
+    }
+
+    function handlePopState() {
+      return renderPage(gadget, window.location.href, window.location.hash);
+    }
+
+    function handleClick(evt) {
+      var target_element = evt.target.closest('a'),
+        base_uri = document.baseURI,
+        link_url;
+
+      if (!target_element) {
+        // Only handle link
+        return;
+      }
+      if (target_element.target === "_blank") {
+        // Open in a new tab
+        return;
+      }
+      if (evt.altKey || evt.ctrlKey || evt.metaKey || evt.shiftKey) {
+        return;
+      }
+
+      link_url = new URL(target_element.href, base_uri);
+      if (link_url.href.indexOf(base_uri) !== 0) {
+        // Only handle sub path of the base url
+        return;
+      }
+
+      if (link_url.hash) {
+        // If new link has an hash, check if the path/query parts are identical
+        // if so, do not refresh the content and
+        // let browser scroll to the correct element
+        if (removeHash(link_url.href) === removeHash(window.location.href)) {
+          return;
+        }
+      }
+
+      evt.preventDefault();
+      return renderPage(gadget, target_element.href, link_url.hash)
+        .push(function () {
+          // Important: pushState must be called AFTER the page rendering
+          // to ensure popstate listener is correctly working
+          // when the user will click on back/forward browser buttons
+          history.pushState(null, null, target_element.href);
+        }, function (error) {
+          // Implement support for managed error
+          // (like URL is not an HTML document parsable)
+          // and redirect in such case
+          window.location = target_element.href;
+        });
+    }
+
+    return RSVP.all([
+      loopEventListener(window, 'popstate', false, handlePopState, false),
+      loopEventListener(gadget.element, 'click', false, handleClick,
+                        false)
+    ]);
+  }
+
+  rJS(window)
+    .ready(function () {
+      // Hide the page as fast as possible
+      // this.element.hidden = true;
+      this.main_element = this.element.querySelector('main');
+    })
+    .allowPublicAcquisition("reportServiceError", function () {
+      this.element.hidden = false;
+      throw rJS.AcquisitionError();
+    })
+    .declareJob("listenURLChange", listenURLChange)
+    .declareService(function () {
+      var gadget = this,
+        style_gadget,
+        body = gadget.element,
+        style_gadget_url = body.getAttribute("data-nostyle-gadget-url");
+
+      if (!style_gadget_url) {
+        // No style configured, use backend only rendering
+        return rJS.declareCSS("jsstyle.css", document.head);
+      }
+
+      // Clear the DOM
+      while (body.firstChild) {
+        body.firstChild.remove();
+      }
+      return gadget.declareGadget(style_gadget_url, {scope: 'renderer'})
+        .push(function (result) {
+          style_gadget = result;
+          return style_gadget.render(gadget.main_element.innerHTML);
+        })
+        .push(function () {
+          // Trigger URL handling
+          gadget.listenURLChange();
+
+          body.appendChild(style_gadget.element);
+          gadget.element.hidden = false;
+          scrollToHash(window.location.hash);
+        }, function (error) {
+          gadget.element.hidden = false;
+          throw error;
+        });
+    });
+
+}(window, document, RSVP, rJS, XMLHttpRequest, DOMParser, URL,
+  loopEventListener, history));
\ No newline at end of file
diff --git a/bt5/erp5_web_js_style/SkinTemplateItem/portal_skins/erp5_web_js_style_ui/jsstyle.js.xml b/bt5/erp5_web_js_style/SkinTemplateItem/portal_skins/erp5_web_js_style_ui/jsstyle.js.xml
new file mode 100644
index 0000000000000000000000000000000000000000..dab2c34b52bf7071ebbd902288cb60a7c3325639
--- /dev/null
+++ b/bt5/erp5_web_js_style/SkinTemplateItem/portal_skins/erp5_web_js_style_ui/jsstyle.js.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0"?>
+<ZopeData>
+  <record id="1" aka="AAAAAAAAAAE=">
+    <pickle>
+      <global name="File" module="OFS.Image"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>_Cacheable__manager_id</string> </key>
+            <value> <string>http_cache</string> </value>
+        </item>
+        <item>
+            <key> <string>__name__</string> </key>
+            <value> <string>jsstyle.js</string> </value>
+        </item>
+        <item>
+            <key> <string>content_type</string> </key>
+            <value> <string>application/javascript</string> </value>
+        </item>
+        <item>
+            <key> <string>precondition</string> </key>
+            <value> <string></string> </value>
+        </item>
+        <item>
+            <key> <string>title</string> </key>
+            <value> <string></string> </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+</ZopeData>
diff --git a/bt5/erp5_web_js_style/SkinTemplateItem/portal_skins/erp5_web_js_style_ui/jsstyle.less.bin b/bt5/erp5_web_js_style/SkinTemplateItem/portal_skins/erp5_web_js_style_ui/jsstyle.less.bin
new file mode 100644
index 0000000000000000000000000000000000000000..002d3301f3080e0c6e108743b88e0346eb29f160
--- /dev/null
+++ b/bt5/erp5_web_js_style/SkinTemplateItem/portal_skins/erp5_web_js_style_ui/jsstyle.less.bin
@@ -0,0 +1,63 @@
+.flattenNav() {
+  background-color: #DDD;
+
+  // Put the title and the first list on the same line
+  display: flex;
+  flex-wrap: wrap;
+  justify-content: space-between;
+
+  // Increase header size
+  min-height: 2.5em;
+  align-items: center;
+
+  > a {
+    padding-left: 1em;
+    padding-right: 1em;
+  }
+
+  ul {
+    margin: 0;
+  }
+  ul, li, a {
+    padding: 0;
+    display: flex;
+    flex: 1;
+    &:not(:first-child) {
+      padding: 0 1em;
+    }
+  }
+}
+
+body {
+  display: grid;
+  grid-template-raws: repeat(3, 1fr); 
+
+  > nav#sitemap {
+    grid-row: 1;
+
+    .flattenNav();
+  }
+
+  main {
+    grid-row: 2;
+
+    fieldset {
+      border: none;
+      > div {
+        display: flex;
+        flex-flow: row nowrap;
+        > label {
+          margin-right: 1em;
+          font-weight: bold;
+          min-width: 10%;
+        }
+      }
+    }
+  }
+
+  > nav#language {
+    grid-row: 3;
+
+    .flattenNav();
+  }
+}
\ No newline at end of file
diff --git a/bt5/erp5_web_js_style/SkinTemplateItem/portal_skins/erp5_web_js_style_ui/jsstyle.less.xml b/bt5/erp5_web_js_style/SkinTemplateItem/portal_skins/erp5_web_js_style_ui/jsstyle.less.xml
new file mode 100644
index 0000000000000000000000000000000000000000..85490859673f7908a3199d3895b6292e51dd06f7
--- /dev/null
+++ b/bt5/erp5_web_js_style/SkinTemplateItem/portal_skins/erp5_web_js_style_ui/jsstyle.less.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0"?>
+<ZopeData>
+  <record id="1" aka="AAAAAAAAAAE=">
+    <pickle>
+      <global name="File" module="OFS.Image"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>_Cacheable__manager_id</string> </key>
+            <value> <string>http_cache</string> </value>
+        </item>
+        <item>
+            <key> <string>__name__</string> </key>
+            <value> <string>jsstyle.less</string> </value>
+        </item>
+        <item>
+            <key> <string>content_type</string> </key>
+            <value> <string>text/less</string> </value>
+        </item>
+        <item>
+            <key> <string>precondition</string> </key>
+            <value> <string></string> </value>
+        </item>
+        <item>
+            <key> <string>title</string> </key>
+            <value> <string></string> </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+</ZopeData>
diff --git a/bt5/erp5_web_js_style/SkinTemplateItem/portal_skins/erp5_web_js_style_ui/jsstyle_demo.css.css b/bt5/erp5_web_js_style/SkinTemplateItem/portal_skins/erp5_web_js_style_ui/jsstyle_demo.css.css
new file mode 100644
index 0000000000000000000000000000000000000000..3901f3b0c2b46238df7e4d38d26b0cf08c5d1e4f
--- /dev/null
+++ b/bt5/erp5_web_js_style/SkinTemplateItem/portal_skins/erp5_web_js_style_ui/jsstyle_demo.css.css
@@ -0,0 +1,8 @@
+body, a {
+  background-color: black;
+  color: white;
+}
+body {max-width: 40em;}
+label {display: block;}
+input:not([type=submit]):not([type=file]) {width: 100%;}
+textarea {height: 15em;width: 100%;}
\ No newline at end of file
diff --git a/bt5/erp5_web_js_style/SkinTemplateItem/portal_skins/erp5_web_js_style_ui/jsstyle_demo.css.xml b/bt5/erp5_web_js_style/SkinTemplateItem/portal_skins/erp5_web_js_style_ui/jsstyle_demo.css.xml
new file mode 100644
index 0000000000000000000000000000000000000000..09d238d5669c6339106e921831fe13ee54193bdc
--- /dev/null
+++ b/bt5/erp5_web_js_style/SkinTemplateItem/portal_skins/erp5_web_js_style_ui/jsstyle_demo.css.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0"?>
+<ZopeData>
+  <record id="1" aka="AAAAAAAAAAE=">
+    <pickle>
+      <global name="File" module="OFS.Image"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>_Cacheable__manager_id</string> </key>
+            <value> <string>http_cache</string> </value>
+        </item>
+        <item>
+            <key> <string>__name__</string> </key>
+            <value> <string>jsstyle_demo.css</string> </value>
+        </item>
+        <item>
+            <key> <string>content_type</string> </key>
+            <value> <string>text/css</string> </value>
+        </item>
+        <item>
+            <key> <string>precondition</string> </key>
+            <value> <string></string> </value>
+        </item>
+        <item>
+            <key> <string>title</string> </key>
+            <value> <string></string> </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+</ZopeData>
diff --git a/bt5/erp5_web_js_style/SkinTemplateItem/portal_skins/erp5_web_js_style_ui/jsstyle_demo.html.html b/bt5/erp5_web_js_style/SkinTemplateItem/portal_skins/erp5_web_js_style_ui/jsstyle_demo.html.html
new file mode 100644
index 0000000000000000000000000000000000000000..1359208d91aa363e994ab816c723535cd46d8b41
--- /dev/null
+++ b/bt5/erp5_web_js_style/SkinTemplateItem/portal_skins/erp5_web_js_style_ui/jsstyle_demo.html.html
@@ -0,0 +1,12 @@
+<html>
+  <head>
+  <link rel="stylesheet" href="jsstyle_demo.css">
+  <script src="portal_skins/erp5_xhtml_style/rsvp.js"></script>
+  <script src="portal_skins/erp5_xhtml_style/renderjs.js"></script>
+  <script src="jsstyle_demo.js"></script>
+  </head>
+  <body>
+    <header><h1>JS Style Demo</h1></header>
+    <main></main>
+  </body>
+</html>
\ No newline at end of file
diff --git a/bt5/erp5_web_js_style/SkinTemplateItem/portal_skins/erp5_web_js_style_ui/jsstyle_demo.html.xml b/bt5/erp5_web_js_style/SkinTemplateItem/portal_skins/erp5_web_js_style_ui/jsstyle_demo.html.xml
new file mode 100644
index 0000000000000000000000000000000000000000..a4990e81c2158844ce4dd7837d0601750024e3e2
--- /dev/null
+++ b/bt5/erp5_web_js_style/SkinTemplateItem/portal_skins/erp5_web_js_style_ui/jsstyle_demo.html.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0"?>
+<ZopeData>
+  <record id="1" aka="AAAAAAAAAAE=">
+    <pickle>
+      <global name="File" module="OFS.Image"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>_Cacheable__manager_id</string> </key>
+            <value> <string>http_cache</string> </value>
+        </item>
+        <item>
+            <key> <string>__name__</string> </key>
+            <value> <string>jsstyle_demo.html</string> </value>
+        </item>
+        <item>
+            <key> <string>content_type</string> </key>
+            <value> <string>text/html</string> </value>
+        </item>
+        <item>
+            <key> <string>precondition</string> </key>
+            <value> <string></string> </value>
+        </item>
+        <item>
+            <key> <string>title</string> </key>
+            <value> <string></string> </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+</ZopeData>
diff --git a/bt5/erp5_web_js_style/SkinTemplateItem/portal_skins/erp5_web_js_style_ui/jsstyle_demo.js.js b/bt5/erp5_web_js_style/SkinTemplateItem/portal_skins/erp5_web_js_style_ui/jsstyle_demo.js.js
new file mode 100644
index 0000000000000000000000000000000000000000..a8d6b8795a85a11891b6f416554594b848821b48
--- /dev/null
+++ b/bt5/erp5_web_js_style/SkinTemplateItem/portal_skins/erp5_web_js_style_ui/jsstyle_demo.js.js
@@ -0,0 +1,14 @@
+/*globals window, document, RSVP, rJS*/
+/*jslint indent: 2, maxlen: 80*/
+(function () {
+  "use strict";
+
+  rJS(window)
+    .declareMethod("render", function (main_innerhtml) {
+      var gadget = this;
+      var div = document.createElement('div');
+      div.innerHTML = main_innerhtml;
+      gadget.element.querySelector('main').innerHTML = div.querySelector('div.input').firstChild.innerHTML;
+    });
+
+}());
\ No newline at end of file
diff --git a/bt5/erp5_web_js_style/SkinTemplateItem/portal_skins/erp5_web_js_style_ui/jsstyle_demo.js.xml b/bt5/erp5_web_js_style/SkinTemplateItem/portal_skins/erp5_web_js_style_ui/jsstyle_demo.js.xml
new file mode 100644
index 0000000000000000000000000000000000000000..1537979d5de7b0047be498e77ee42f0f480553ce
--- /dev/null
+++ b/bt5/erp5_web_js_style/SkinTemplateItem/portal_skins/erp5_web_js_style_ui/jsstyle_demo.js.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0"?>
+<ZopeData>
+  <record id="1" aka="AAAAAAAAAAE=">
+    <pickle>
+      <global name="File" module="OFS.Image"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>_Cacheable__manager_id</string> </key>
+            <value> <string>http_cache</string> </value>
+        </item>
+        <item>
+            <key> <string>__name__</string> </key>
+            <value> <string>jsstyle_demo.js</string> </value>
+        </item>
+        <item>
+            <key> <string>content_type</string> </key>
+            <value> <string>application/javascript</string> </value>
+        </item>
+        <item>
+            <key> <string>precondition</string> </key>
+            <value> <string></string> </value>
+        </item>
+        <item>
+            <key> <string>title</string> </key>
+            <value> <string></string> </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+</ZopeData>
diff --git a/bt5/erp5_web_js_style/SkinTemplateItem/portal_skins/erp5_web_js_style_ui/view_main.xml b/bt5/erp5_web_js_style/SkinTemplateItem/portal_skins/erp5_web_js_style_ui/view_main.xml
new file mode 100644
index 0000000000000000000000000000000000000000..61d8d98db6f293aa4765ba3e05b335c295a1d3cd
--- /dev/null
+++ b/bt5/erp5_web_js_style/SkinTemplateItem/portal_skins/erp5_web_js_style_ui/view_main.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0"?>
+<ZopeData>
+  <record id="1" aka="AAAAAAAAAAE=">
+    <pickle>
+      <global name="ZopePageTemplate" module="Products.PageTemplates.ZopePageTemplate"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>_bind_names</string> </key>
+            <value>
+              <object>
+                <klass>
+                  <global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
+                </klass>
+                <tuple/>
+                <state>
+                  <dictionary>
+                    <item>
+                        <key> <string>_asgns</string> </key>
+                        <value>
+                          <dictionary>
+                            <item>
+                                <key> <string>name_subpath</string> </key>
+                                <value> <string>traverse_subpath</string> </value>
+                            </item>
+                          </dictionary>
+                        </value>
+                    </item>
+                  </dictionary>
+                </state>
+              </object>
+            </value>
+        </item>
+        <item>
+            <key> <string>content_type</string> </key>
+            <value> <string>text/html</string> </value>
+        </item>
+        <item>
+            <key> <string>expand</string> </key>
+            <value> <int>0</int> </value>
+        </item>
+        <item>
+            <key> <string>id</string> </key>
+            <value> <string>view_main</string> </value>
+        </item>
+        <item>
+            <key> <string>output_encoding</string> </key>
+            <value> <string>utf-8</string> </value>
+        </item>
+        <item>
+            <key> <string>title</string> </key>
+            <value> <unicode></unicode> </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+</ZopeData>
diff --git a/bt5/erp5_web_js_style/SkinTemplateItem/portal_skins/erp5_web_js_style_ui/view_main.zpt b/bt5/erp5_web_js_style/SkinTemplateItem/portal_skins/erp5_web_js_style_ui/view_main.zpt
new file mode 100644
index 0000000000000000000000000000000000000000..383a54466ec39f55df4519b9efbbfad2b5a500a8
--- /dev/null
+++ b/bt5/erp5_web_js_style/SkinTemplateItem/portal_skins/erp5_web_js_style_ui/view_main.zpt
@@ -0,0 +1,35 @@
+<tal:block xmlns:tal="http://xml.zope.org/namespaces/tal"
+           xmlns:metal="http://xml.zope.org/namespaces/metal"
+           xmlns:i18n="http://xml.zope.org/namespaces/i18n">
+
+  <tal:block metal:define-macro="master">
+    <tal:block tal:define="
+      dummy python: request.set('is_web_mode', True);
+      dummy python: request.set('ignore_layout', False);
+      dummy python: request.set('editable_mode', False);
+      web_site python: here.getWebSiteValue();
+      global_definitions_macros here/global_definitions/macros;">
+      <tal:block metal:use-macro="global_definitions_macros/header_definitions" />
+<html>
+  <head>
+  <base tal:attributes="href python: '%s/' % web_site.absolute_url()" />
+  <meta name="viewport" content="width=device-width,height=device-height,initial-scale=1" />
+  <title tal:content="python: here.getTranslatedTitle() or web_site.getTranslatedTitle()"></title>
+  <noscript>
+    <link rel="stylesheet" href="jsstyle.css">
+  </noscript>
+  <!-- Prevent conflicts with Web Page reference provided by erp5_web_renderjs_ui -->
+  <script src="portal_skins/erp5_xhtml_style/rsvp.js"></script>
+  <script src="portal_skins/erp5_xhtml_style/renderjs.js"></script>
+  <script src="gadget_global.js"></script>
+  <script src="jsstyle.js"></script>
+  </head>
+  <body tal:attributes="data-nostyle-gadget-url python: web_site.getLayoutProperty('configuration_style_gadget_url', default='')">
+    <tal:block tal:content="structure python: web_site.WebSite_generateNavigationHTML()"></tal:block>
+    <main><tal:block metal:define-slot="main"/></main>
+  </body>
+</html>
+    </tal:block>
+  </tal:block>
+
+</tal:block>
\ No newline at end of file
diff --git a/bt5/erp5_web_js_style/bt/dependency_list b/bt5/erp5_web_js_style/bt/dependency_list
new file mode 100644
index 0000000000000000000000000000000000000000..8853475efb427de8addedf1d20d85367cf077b81
--- /dev/null
+++ b/bt5/erp5_web_js_style/bt/dependency_list
@@ -0,0 +1 @@
+erp5_web
\ No newline at end of file
diff --git a/bt5/erp5_web_js_style/bt/license b/bt5/erp5_web_js_style/bt/license
new file mode 100644
index 0000000000000000000000000000000000000000..3a3e12bcad97e4b3bdd6a8bb499fd23a4bcb0819
--- /dev/null
+++ b/bt5/erp5_web_js_style/bt/license
@@ -0,0 +1 @@
+GPL
\ No newline at end of file
diff --git a/bt5/erp5_web_js_style/bt/template_format_version b/bt5/erp5_web_js_style/bt/template_format_version
new file mode 100644
index 0000000000000000000000000000000000000000..56a6051ca2b02b04ef92d5150c9ef600403cb1de
--- /dev/null
+++ b/bt5/erp5_web_js_style/bt/template_format_version
@@ -0,0 +1 @@
+1
\ No newline at end of file
diff --git a/bt5/erp5_web_js_style/bt/template_registered_skin_selection_list b/bt5/erp5_web_js_style/bt/template_registered_skin_selection_list
new file mode 100644
index 0000000000000000000000000000000000000000..50919251ff6b435e320bf4cb2449604cbb4f24dd
--- /dev/null
+++ b/bt5/erp5_web_js_style/bt/template_registered_skin_selection_list
@@ -0,0 +1,2 @@
+erp5_web_js_style_ui | Jsstyle
+erp5_xhtml_style | Jsstyle
\ No newline at end of file
diff --git a/bt5/erp5_web_js_style/bt/template_skin_id_list b/bt5/erp5_web_js_style/bt/template_skin_id_list
new file mode 100644
index 0000000000000000000000000000000000000000..25647a8c0b96367a344fc692ed00d01225a47209
--- /dev/null
+++ b/bt5/erp5_web_js_style/bt/template_skin_id_list
@@ -0,0 +1,2 @@
+erp5_web_js_style
+erp5_web_js_style_ui
\ No newline at end of file
diff --git a/bt5/erp5_web_js_style/bt/title b/bt5/erp5_web_js_style/bt/title
new file mode 100644
index 0000000000000000000000000000000000000000..ba0dffcda1ac04b0be81369c7e377995a297aa3c
--- /dev/null
+++ b/bt5/erp5_web_js_style/bt/title
@@ -0,0 +1 @@
+erp5_web_js_style
\ No newline at end of file
diff --git a/bt5/erp5_web_js_style/bt/version b/bt5/erp5_web_js_style/bt/version
new file mode 100644
index 0000000000000000000000000000000000000000..ceab6e11ece0bcec917c12e11d350946f085d549
--- /dev/null
+++ b/bt5/erp5_web_js_style/bt/version
@@ -0,0 +1 @@
+0.1
\ No newline at end of file
diff --git a/bt5/erp5_web_js_style_test/PathTemplateItem/portal_tests/js_style_zuite.xml b/bt5/erp5_web_js_style_test/PathTemplateItem/portal_tests/js_style_zuite.xml
new file mode 100644
index 0000000000000000000000000000000000000000..661be7500d33d8a2a8875f001bdcc8f96fc08ec5
--- /dev/null
+++ b/bt5/erp5_web_js_style_test/PathTemplateItem/portal_tests/js_style_zuite.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0"?>
+<ZopeData>
+  <record id="1" aka="AAAAAAAAAAE=">
+    <pickle>
+      <global name="Zuite" module="Products.Zelenium.zuite"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>_objects</string> </key>
+            <value>
+              <tuple/>
+            </value>
+        </item>
+        <item>
+            <key> <string>id</string> </key>
+            <value> <string>js_style_zuite</string> </value>
+        </item>
+        <item>
+            <key> <string>title</string> </key>
+            <value> <string></string> </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+</ZopeData>
diff --git a/bt5/erp5_web_js_style_test/PathTemplateItem/portal_tests/js_style_zuite/testJsStyleDemoStyle.xml b/bt5/erp5_web_js_style_test/PathTemplateItem/portal_tests/js_style_zuite/testJsStyleDemoStyle.xml
new file mode 100644
index 0000000000000000000000000000000000000000..9991922b59c873a624508bba9a26dff48459e4ef
--- /dev/null
+++ b/bt5/erp5_web_js_style_test/PathTemplateItem/portal_tests/js_style_zuite/testJsStyleDemoStyle.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0"?>
+<ZopeData>
+  <record id="1" aka="AAAAAAAAAAE=">
+    <pickle>
+      <global name="ZopePageTemplate" module="Products.PageTemplates.ZopePageTemplate"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>_bind_names</string> </key>
+            <value>
+              <object>
+                <klass>
+                  <global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
+                </klass>
+                <tuple/>
+                <state>
+                  <dictionary>
+                    <item>
+                        <key> <string>_asgns</string> </key>
+                        <value>
+                          <dictionary>
+                            <item>
+                                <key> <string>name_subpath</string> </key>
+                                <value> <string>traverse_subpath</string> </value>
+                            </item>
+                          </dictionary>
+                        </value>
+                    </item>
+                  </dictionary>
+                </state>
+              </object>
+            </value>
+        </item>
+        <item>
+            <key> <string>content_type</string> </key>
+            <value> <string>text/html</string> </value>
+        </item>
+        <item>
+            <key> <string>expand</string> </key>
+            <value> <int>0</int> </value>
+        </item>
+        <item>
+            <key> <string>id</string> </key>
+            <value> <string>testJsStyleDemoStyle</string> </value>
+        </item>
+        <item>
+            <key> <string>output_encoding</string> </key>
+            <value> <string>utf-8</string> </value>
+        </item>
+        <item>
+            <key> <string>title</string> </key>
+            <value> <unicode></unicode> </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+</ZopeData>
diff --git a/bt5/erp5_web_js_style_test/PathTemplateItem/portal_tests/js_style_zuite/testJsStyleDemoStyle.zpt b/bt5/erp5_web_js_style_test/PathTemplateItem/portal_tests/js_style_zuite/testJsStyleDemoStyle.zpt
new file mode 100644
index 0000000000000000000000000000000000000000..0e95595ff8e8b7582dcf54f04844f234f3f43983
--- /dev/null
+++ b/bt5/erp5_web_js_style_test/PathTemplateItem/portal_tests/js_style_zuite/testJsStyleDemoStyle.zpt
@@ -0,0 +1,57 @@
+<html xmlns:tal="http://xml.zope.org/namespaces/tal"
+      xmlns:metal="http://xml.zope.org/namespaces/metal">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Test JS Style Demo Style</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Test JS Style Demo Style</td></tr>
+</thead><tbody>
+<tal:block metal:use-macro="here/Zuite_CommonTemplate/macros/init" />
+
+<!-- Initialize -->
+<tr>
+  <td>open</td>
+  <td>${base_url}/web_site_module/test_js_style_demo_style/</td>
+  <td></td>
+</tr>
+
+<tr>
+  <td>waitForElementPresent</td>
+  <td>//header/h1[text()='JS Style Demo']</td>
+  <td></td>
+</tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//header/h1[text()='JS Style Demo']</td>
+  <td></td>
+</tr>
+
+<tr>
+  <td>assertElementNotPresent</td>
+  <td>//nav[@id='sitemap']/a[text()='No Style']</td>
+  <td></td>
+</tr>
+
+<tr>
+  <td>assertElementNotPresent</td>
+  <td>//nav[@id='language']//a[@hreflang='en']</td>
+  <td></td>
+</tr>
+
+<tr>
+  <td>assertElementNotPresent</td>
+  <td>//div[@class='input']/span[@class='headline' and text()='Demo Style']</td>
+  <td></td>
+</tr>
+<tr>
+  <td>assertElementPresent</td>
+  <td>//main[text()='Demo Style']</td>
+  <td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
\ No newline at end of file
diff --git a/bt5/erp5_web_js_style_test/PathTemplateItem/portal_tests/js_style_zuite/testJsStyleNoStyle.xml b/bt5/erp5_web_js_style_test/PathTemplateItem/portal_tests/js_style_zuite/testJsStyleNoStyle.xml
new file mode 100644
index 0000000000000000000000000000000000000000..c8c213aefa40e350fadb1cad8011ee27a745e376
--- /dev/null
+++ b/bt5/erp5_web_js_style_test/PathTemplateItem/portal_tests/js_style_zuite/testJsStyleNoStyle.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0"?>
+<ZopeData>
+  <record id="1" aka="AAAAAAAAAAE=">
+    <pickle>
+      <global name="ZopePageTemplate" module="Products.PageTemplates.ZopePageTemplate"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>_bind_names</string> </key>
+            <value>
+              <object>
+                <klass>
+                  <global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
+                </klass>
+                <tuple/>
+                <state>
+                  <dictionary>
+                    <item>
+                        <key> <string>_asgns</string> </key>
+                        <value>
+                          <dictionary>
+                            <item>
+                                <key> <string>name_subpath</string> </key>
+                                <value> <string>traverse_subpath</string> </value>
+                            </item>
+                          </dictionary>
+                        </value>
+                    </item>
+                  </dictionary>
+                </state>
+              </object>
+            </value>
+        </item>
+        <item>
+            <key> <string>content_type</string> </key>
+            <value> <string>text/html</string> </value>
+        </item>
+        <item>
+            <key> <string>expand</string> </key>
+            <value> <int>0</int> </value>
+        </item>
+        <item>
+            <key> <string>id</string> </key>
+            <value> <string>testJsStyleNoStyle</string> </value>
+        </item>
+        <item>
+            <key> <string>output_encoding</string> </key>
+            <value> <string>utf-8</string> </value>
+        </item>
+        <item>
+            <key> <string>title</string> </key>
+            <value> <unicode></unicode> </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+</ZopeData>
diff --git a/bt5/erp5_web_js_style_test/PathTemplateItem/portal_tests/js_style_zuite/testJsStyleNoStyle.zpt b/bt5/erp5_web_js_style_test/PathTemplateItem/portal_tests/js_style_zuite/testJsStyleNoStyle.zpt
new file mode 100644
index 0000000000000000000000000000000000000000..d9546e601d276dc7492e1a023e6b432a9b389b03
--- /dev/null
+++ b/bt5/erp5_web_js_style_test/PathTemplateItem/portal_tests/js_style_zuite/testJsStyleNoStyle.zpt
@@ -0,0 +1,41 @@
+<html xmlns:tal="http://xml.zope.org/namespaces/tal"
+      xmlns:metal="http://xml.zope.org/namespaces/metal">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Test JS Style No Style</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Test JS Style No Style</td></tr>
+</thead><tbody>
+<tal:block metal:use-macro="here/Zuite_CommonTemplate/macros/init" />
+
+<!-- Initialize -->
+<tr>
+  <td>open</td>
+  <td>${base_url}/web_site_module/test_js_style_no_style/</td>
+  <td></td>
+</tr>
+
+<tr>
+  <td>assertElementPresent</td>
+  <td>//nav[@id='sitemap']/a[text()='No Style']</td>
+  <td></td>
+</tr>
+
+<tr>
+  <td>assertElementPresent</td>
+  <td>//nav[@id='language']//a[@hreflang='en']</td>
+  <td></td>
+</tr>
+
+<tr>
+  <td>assertElementPresent</td>
+  <td>//div[@class='input']/span[@class='headline' and text()='No Style']</td>
+  <td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
\ No newline at end of file
diff --git a/bt5/erp5_web_js_style_test/PathTemplateItem/web_site_module/test_js_style_demo_style.xml b/bt5/erp5_web_js_style_test/PathTemplateItem/web_site_module/test_js_style_demo_style.xml
new file mode 100644
index 0000000000000000000000000000000000000000..83e277909fc404e8f87d54fe7a7dbe4dc8ef9b5f
--- /dev/null
+++ b/bt5/erp5_web_js_style_test/PathTemplateItem/web_site_module/test_js_style_demo_style.xml
@@ -0,0 +1,241 @@
+<?xml version="1.0"?>
+<ZopeData>
+  <record id="1" aka="AAAAAAAAAAE=">
+    <pickle>
+      <global name="Web Site" module="erp5.portal_type"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>_Add_portal_content_Permission</string> </key>
+            <value>
+              <tuple>
+                <string>Assignor</string>
+                <string>Manager</string>
+              </tuple>
+            </value>
+        </item>
+        <item>
+            <key> <string>_Add_portal_folders_Permission</string> </key>
+            <value>
+              <tuple>
+                <string>Assignor</string>
+                <string>Manager</string>
+              </tuple>
+            </value>
+        </item>
+        <item>
+            <key> <string>_Copy_or_Move_Permission</string> </key>
+            <value>
+              <tuple>
+                <string>Assignor</string>
+                <string>Manager</string>
+              </tuple>
+            </value>
+        </item>
+        <item>
+            <key> <string>_Delete_objects_Permission</string> </key>
+            <value>
+              <tuple>
+                <string>Assignor</string>
+                <string>Manager</string>
+              </tuple>
+            </value>
+        </item>
+        <item>
+            <key> <string>_Modify_portal_content_Permission</string> </key>
+            <value>
+              <tuple>
+                <string>Assignee</string>
+                <string>Assignor</string>
+                <string>Manager</string>
+                <string>Owner</string>
+              </tuple>
+            </value>
+        </item>
+        <item>
+            <key> <string>__before_publishing_traverse__</string> </key>
+            <value>
+              <object>
+                <klass>
+                  <global name="MultiHook" module="ZPublisher.BeforeTraverse"/>
+                </klass>
+                <tuple/>
+                <state>
+                  <dictionary>
+                    <item>
+                        <key> <string>_defined_in_class</string> </key>
+                        <value> <int>1</int> </value>
+                    </item>
+                    <item>
+                        <key> <string>_hookname</string> </key>
+                        <value> <string>__before_publishing_traverse__</string> </value>
+                    </item>
+                    <item>
+                        <key> <string>_list</string> </key>
+                        <value>
+                          <list>
+                            <persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
+                          </list>
+                        </value>
+                    </item>
+                    <item>
+                        <key> <string>_prior</string> </key>
+                        <value>
+                          <none/>
+                        </value>
+                    </item>
+                  </dictionary>
+                </state>
+              </object>
+            </value>
+        </item>
+        <item>
+            <key> <string>__before_traverse__</string> </key>
+            <value>
+              <dictionary>
+                <item>
+                    <key>
+                      <tuple>
+                        <int>99</int>
+                        <string>ERP5 Web Site/test_js_style_demo_style</string>
+                      </tuple>
+                    </key>
+                    <value>
+                      <persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
+                    </value>
+                </item>
+              </dictionary>
+            </value>
+        </item>
+        <item>
+            <key> <string>_identity_criterion</string> </key>
+            <value>
+              <persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
+            </value>
+        </item>
+        <item>
+            <key> <string>_local_properties</string> </key>
+            <value>
+              <tuple>
+                <dictionary>
+                  <item>
+                      <key> <string>id</string> </key>
+                      <value> <string>configuration_style_gadget_url</string> </value>
+                  </item>
+                  <item>
+                      <key> <string>type</string> </key>
+                      <value> <string>string</string> </value>
+                  </item>
+                </dictionary>
+              </tuple>
+            </value>
+        </item>
+        <item>
+            <key> <string>_range_criterion</string> </key>
+            <value>
+              <persistent> <string encoding="base64">AAAAAAAAAAQ=</string> </persistent>
+            </value>
+        </item>
+        <item>
+            <key> <string>available_language</string> </key>
+            <value>
+              <tuple>
+                <string>en</string>
+              </tuple>
+            </value>
+        </item>
+        <item>
+            <key> <string>configuration_style_gadget_url</string> </key>
+            <value> <string>jsstyle_demo.html</string> </value>
+        </item>
+        <item>
+            <key> <string>container_layout</string> </key>
+            <value> <string>erp5_web_layout</string> </value>
+        </item>
+        <item>
+            <key> <string>content_layout</string> </key>
+            <value> <string>erp5_web_content_layout</string> </value>
+        </item>
+        <item>
+            <key> <string>description</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>id</string> </key>
+            <value> <string>test_js_style_demo_style</string> </value>
+        </item>
+        <item>
+            <key> <string>layout_configuration_form_id</string> </key>
+            <value> <string>WebSection_viewJsstylePreference</string> </value>
+        </item>
+        <item>
+            <key> <string>portal_type</string> </key>
+            <value> <string>Web Site</string> </value>
+        </item>
+        <item>
+            <key> <string>short_title</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>skin_selection_name</string> </key>
+            <value> <string>Jsstyle</string> </value>
+        </item>
+        <item>
+            <key> <string>static_language_selection</string> </key>
+            <value> <int>1</int> </value>
+        </item>
+        <item>
+            <key> <string>title</string> </key>
+            <value> <string>Demo Style</string> </value>
+        </item>
+        <item>
+            <key> <string>visible</string> </key>
+            <value> <int>0</int> </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+  <record id="2" aka="AAAAAAAAAAI=">
+    <pickle>
+      <global name="WebSiteTraversalHook" module="Products.ERP5.Document.WebSite"/>
+    </pickle>
+    <pickle>
+      <dictionary/>
+    </pickle>
+  </record>
+  <record id="3" aka="AAAAAAAAAAM=">
+    <pickle>
+      <global name="PersistentMapping" module="Persistence.mapping"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>data</string> </key>
+            <value>
+              <dictionary/>
+            </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+  <record id="4" aka="AAAAAAAAAAQ=">
+    <pickle>
+      <global name="PersistentMapping" module="Persistence.mapping"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>data</string> </key>
+            <value>
+              <dictionary/>
+            </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+</ZopeData>
diff --git a/bt5/erp5_web_js_style_test/PathTemplateItem/web_site_module/test_js_style_no_style.xml b/bt5/erp5_web_js_style_test/PathTemplateItem/web_site_module/test_js_style_no_style.xml
new file mode 100644
index 0000000000000000000000000000000000000000..024f371fe56cbed05bea4bbc5e9dd3a9c4e295ce
--- /dev/null
+++ b/bt5/erp5_web_js_style_test/PathTemplateItem/web_site_module/test_js_style_no_style.xml
@@ -0,0 +1,220 @@
+<?xml version="1.0"?>
+<ZopeData>
+  <record id="1" aka="AAAAAAAAAAE=">
+    <pickle>
+      <global name="Web Site" module="erp5.portal_type"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>_Add_portal_content_Permission</string> </key>
+            <value>
+              <tuple>
+                <string>Assignor</string>
+                <string>Manager</string>
+              </tuple>
+            </value>
+        </item>
+        <item>
+            <key> <string>_Add_portal_folders_Permission</string> </key>
+            <value>
+              <tuple>
+                <string>Assignor</string>
+                <string>Manager</string>
+              </tuple>
+            </value>
+        </item>
+        <item>
+            <key> <string>_Copy_or_Move_Permission</string> </key>
+            <value>
+              <tuple>
+                <string>Assignor</string>
+                <string>Manager</string>
+              </tuple>
+            </value>
+        </item>
+        <item>
+            <key> <string>_Delete_objects_Permission</string> </key>
+            <value>
+              <tuple>
+                <string>Assignor</string>
+                <string>Manager</string>
+              </tuple>
+            </value>
+        </item>
+        <item>
+            <key> <string>_Modify_portal_content_Permission</string> </key>
+            <value>
+              <tuple>
+                <string>Assignee</string>
+                <string>Assignor</string>
+                <string>Manager</string>
+                <string>Owner</string>
+              </tuple>
+            </value>
+        </item>
+        <item>
+            <key> <string>__before_publishing_traverse__</string> </key>
+            <value>
+              <object>
+                <klass>
+                  <global name="MultiHook" module="ZPublisher.BeforeTraverse"/>
+                </klass>
+                <tuple/>
+                <state>
+                  <dictionary>
+                    <item>
+                        <key> <string>_defined_in_class</string> </key>
+                        <value> <int>1</int> </value>
+                    </item>
+                    <item>
+                        <key> <string>_hookname</string> </key>
+                        <value> <string>__before_publishing_traverse__</string> </value>
+                    </item>
+                    <item>
+                        <key> <string>_list</string> </key>
+                        <value>
+                          <list>
+                            <persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
+                          </list>
+                        </value>
+                    </item>
+                    <item>
+                        <key> <string>_prior</string> </key>
+                        <value>
+                          <none/>
+                        </value>
+                    </item>
+                  </dictionary>
+                </state>
+              </object>
+            </value>
+        </item>
+        <item>
+            <key> <string>__before_traverse__</string> </key>
+            <value>
+              <dictionary>
+                <item>
+                    <key>
+                      <tuple>
+                        <int>99</int>
+                        <string>ERP5 Web Site/test_js_style_no_style</string>
+                      </tuple>
+                    </key>
+                    <value>
+                      <persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
+                    </value>
+                </item>
+              </dictionary>
+            </value>
+        </item>
+        <item>
+            <key> <string>_identity_criterion</string> </key>
+            <value>
+              <persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
+            </value>
+        </item>
+        <item>
+            <key> <string>_range_criterion</string> </key>
+            <value>
+              <persistent> <string encoding="base64">AAAAAAAAAAQ=</string> </persistent>
+            </value>
+        </item>
+        <item>
+            <key> <string>available_language</string> </key>
+            <value>
+              <tuple>
+                <string>en</string>
+              </tuple>
+            </value>
+        </item>
+        <item>
+            <key> <string>container_layout</string> </key>
+            <value> <string>erp5_web_layout</string> </value>
+        </item>
+        <item>
+            <key> <string>content_layout</string> </key>
+            <value> <string>erp5_web_content_layout</string> </value>
+        </item>
+        <item>
+            <key> <string>description</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>id</string> </key>
+            <value> <string>test_js_style_no_style</string> </value>
+        </item>
+        <item>
+            <key> <string>layout_configuration_form_id</string> </key>
+            <value> <string>WebSection_viewJsstylePreference</string> </value>
+        </item>
+        <item>
+            <key> <string>portal_type</string> </key>
+            <value> <string>Web Site</string> </value>
+        </item>
+        <item>
+            <key> <string>short_title</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>skin_selection_name</string> </key>
+            <value> <string>Jsstyle</string> </value>
+        </item>
+        <item>
+            <key> <string>static_language_selection</string> </key>
+            <value> <int>1</int> </value>
+        </item>
+        <item>
+            <key> <string>title</string> </key>
+            <value> <string>No Style</string> </value>
+        </item>
+        <item>
+            <key> <string>visible</string> </key>
+            <value> <int>0</int> </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+  <record id="2" aka="AAAAAAAAAAI=">
+    <pickle>
+      <global name="WebSiteTraversalHook" module="Products.ERP5.Document.WebSite"/>
+    </pickle>
+    <pickle>
+      <dictionary/>
+    </pickle>
+  </record>
+  <record id="3" aka="AAAAAAAAAAM=">
+    <pickle>
+      <global name="PersistentMapping" module="Persistence.mapping"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>data</string> </key>
+            <value>
+              <dictionary/>
+            </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+  <record id="4" aka="AAAAAAAAAAQ=">
+    <pickle>
+      <global name="PersistentMapping" module="Persistence.mapping"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>data</string> </key>
+            <value>
+              <dictionary/>
+            </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+</ZopeData>
diff --git a/bt5/erp5_web_js_style_test/TestTemplateItem/portal_components/test.erp5.testFunctionalJsStyle.py b/bt5/erp5_web_js_style_test/TestTemplateItem/portal_components/test.erp5.testFunctionalJsStyle.py
new file mode 100644
index 0000000000000000000000000000000000000000..ed6cf10e35c391429c6c897eb66bce62c73c6578
--- /dev/null
+++ b/bt5/erp5_web_js_style_test/TestTemplateItem/portal_components/test.erp5.testFunctionalJsStyle.py
@@ -0,0 +1,45 @@
+##############################################################################
+#
+# Copyright (c) 2020 Nexedi SARL and Contributors. All Rights Reserved.
+#
+# WARNING: This program as such is intended to be used by professional
+# programmers who take the whole responsability of assessing all potential
+# consequences resulting from its eventual inadequacies and bugs
+# End users who are looking for a ready-to-use solution with commercial
+# garantees and support are strongly adviced to contract a Free Software
+# Service Company
+#
+# This program is Free Software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+#
+##############################################################################
+import unittest
+
+from Products.ERP5Type.tests.ERP5TypeFunctionalTestCase import ERP5TypeFunctionalTestCase
+
+class TestFunctionalJsStyle(ERP5TypeFunctionalTestCase):
+  foreground = 0
+  run_only = "js_style_zuite"
+
+  def getBusinessTemplateList(self):
+    return (
+      'erp5_web_js_style',
+      'erp5_web_js_style_test',
+      'erp5_ui_test_core',
+    )
+
+def test_suite():
+  suite = unittest.TestSuite()
+  suite.addTest(unittest.makeSuite(TestFunctionalJsStyle))
+  return suite
diff --git a/bt5/erp5_web_js_style_test/TestTemplateItem/portal_components/test.erp5.testFunctionalJsStyle.xml b/bt5/erp5_web_js_style_test/TestTemplateItem/portal_components/test.erp5.testFunctionalJsStyle.xml
new file mode 100644
index 0000000000000000000000000000000000000000..19ed7da53daaec7b0937e5cf75d6e730c60c500a
--- /dev/null
+++ b/bt5/erp5_web_js_style_test/TestTemplateItem/portal_components/test.erp5.testFunctionalJsStyle.xml
@@ -0,0 +1,125 @@
+<?xml version="1.0"?>
+<ZopeData>
+  <record id="1" aka="AAAAAAAAAAE=">
+    <pickle>
+      <global name="Test Component" module="erp5.portal_type"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>_recorded_property_dict</string> </key>
+            <value>
+              <persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
+            </value>
+        </item>
+        <item>
+            <key> <string>default_reference</string> </key>
+            <value> <string>testFunctionalJsStyle</string> </value>
+        </item>
+        <item>
+            <key> <string>description</string> </key>
+            <value> <string>Test for JS Style</string> </value>
+        </item>
+        <item>
+            <key> <string>id</string> </key>
+            <value> <string>test.erp5.testFunctionalJsStyle</string> </value>
+        </item>
+        <item>
+            <key> <string>portal_type</string> </key>
+            <value> <string>Test Component</string> </value>
+        </item>
+        <item>
+            <key> <string>sid</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>text_content_error_message</string> </key>
+            <value>
+              <tuple/>
+            </value>
+        </item>
+        <item>
+            <key> <string>text_content_warning_message</string> </key>
+            <value>
+              <tuple/>
+            </value>
+        </item>
+        <item>
+            <key> <string>version</string> </key>
+            <value> <string>erp5</string> </value>
+        </item>
+        <item>
+            <key> <string>workflow_history</string> </key>
+            <value>
+              <persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
+            </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+  <record id="2" aka="AAAAAAAAAAI=">
+    <pickle>
+      <global name="PersistentMapping" module="Persistence.mapping"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>data</string> </key>
+            <value>
+              <dictionary/>
+            </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+  <record id="3" aka="AAAAAAAAAAM=">
+    <pickle>
+      <global name="PersistentMapping" module="Persistence.mapping"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>data</string> </key>
+            <value>
+              <dictionary>
+                <item>
+                    <key> <string>component_validation_workflow</string> </key>
+                    <value>
+                      <persistent> <string encoding="base64">AAAAAAAAAAQ=</string> </persistent>
+                    </value>
+                </item>
+              </dictionary>
+            </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+  <record id="4" aka="AAAAAAAAAAQ=">
+    <pickle>
+      <global name="WorkflowHistoryList" module="Products.ERP5Type.Workflow"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>_log</string> </key>
+            <value>
+              <list>
+                <dictionary>
+                  <item>
+                      <key> <string>action</string> </key>
+                      <value> <string>validate</string> </value>
+                  </item>
+                  <item>
+                      <key> <string>validation_state</string> </key>
+                      <value> <string>validated</string> </value>
+                  </item>
+                </dictionary>
+              </list>
+            </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+</ZopeData>
diff --git a/bt5/erp5_web_js_style_test/bt/dependency_list b/bt5/erp5_web_js_style_test/bt/dependency_list
new file mode 100644
index 0000000000000000000000000000000000000000..7708a0b6d9e28c4b6a5146205cd9d4883dd377d4
--- /dev/null
+++ b/bt5/erp5_web_js_style_test/bt/dependency_list
@@ -0,0 +1,3 @@
+erp5_ui_test_core
+erp5_ui_test
+erp5_web_js_style
\ No newline at end of file
diff --git a/bt5/erp5_web_js_style_test/bt/template_format_version b/bt5/erp5_web_js_style_test/bt/template_format_version
new file mode 100644
index 0000000000000000000000000000000000000000..56a6051ca2b02b04ef92d5150c9ef600403cb1de
--- /dev/null
+++ b/bt5/erp5_web_js_style_test/bt/template_format_version
@@ -0,0 +1 @@
+1
\ No newline at end of file
diff --git a/bt5/erp5_web_js_style_test/bt/template_keep_last_workflow_history_only_path_list b/bt5/erp5_web_js_style_test/bt/template_keep_last_workflow_history_only_path_list
new file mode 100644
index 0000000000000000000000000000000000000000..820ffa936bf3325f3dc1a3c501db2bacf7856532
--- /dev/null
+++ b/bt5/erp5_web_js_style_test/bt/template_keep_last_workflow_history_only_path_list
@@ -0,0 +1 @@
+web_site_module/test_js_style_*_style
\ No newline at end of file
diff --git a/bt5/erp5_web_js_style_test/bt/template_keep_workflow_path_list b/bt5/erp5_web_js_style_test/bt/template_keep_workflow_path_list
new file mode 100644
index 0000000000000000000000000000000000000000..820ffa936bf3325f3dc1a3c501db2bacf7856532
--- /dev/null
+++ b/bt5/erp5_web_js_style_test/bt/template_keep_workflow_path_list
@@ -0,0 +1 @@
+web_site_module/test_js_style_*_style
\ No newline at end of file
diff --git a/bt5/erp5_web_js_style_test/bt/template_path_list b/bt5/erp5_web_js_style_test/bt/template_path_list
new file mode 100644
index 0000000000000000000000000000000000000000..bff295b41c844161f3742d22d03124e3a5abec12
--- /dev/null
+++ b/bt5/erp5_web_js_style_test/bt/template_path_list
@@ -0,0 +1,3 @@
+portal_tests/js_style_zuite
+portal_tests/js_style_zuite/**
+web_site_module/test_js_style_*_style
\ No newline at end of file
diff --git a/bt5/erp5_web_js_style_test/bt/template_test_id_list b/bt5/erp5_web_js_style_test/bt/template_test_id_list
new file mode 100644
index 0000000000000000000000000000000000000000..a528a19e5303750dd49a74b77364b68578f3a813
--- /dev/null
+++ b/bt5/erp5_web_js_style_test/bt/template_test_id_list
@@ -0,0 +1 @@
+test.erp5.testFunctionalJsStyle
\ No newline at end of file
diff --git a/bt5/erp5_web_js_style_test/bt/test_dependency_list b/bt5/erp5_web_js_style_test/bt/test_dependency_list
new file mode 100644
index 0000000000000000000000000000000000000000..bff77e32d84989312efdf3b2caed2e39f9a513ed
--- /dev/null
+++ b/bt5/erp5_web_js_style_test/bt/test_dependency_list
@@ -0,0 +1 @@
+erp5_full_text_mroonga_catalog
\ No newline at end of file
diff --git a/bt5/erp5_web_js_style_test/bt/title b/bt5/erp5_web_js_style_test/bt/title
new file mode 100644
index 0000000000000000000000000000000000000000..168fdeb25f62885fa80b847b40d61d6dd4d41dfe
--- /dev/null
+++ b/bt5/erp5_web_js_style_test/bt/title
@@ -0,0 +1 @@
+erp5_web_js_style_test
\ No newline at end of file