diff --git a/assets/scss/_tocbot.scss b/assets/scss/_tocbot.scss
new file mode 100644
index 0000000000..e5bb569da6
--- /dev/null
+++ b/assets/scss/_tocbot.scss
@@ -0,0 +1,5 @@
+// Tocbot style customization
+
+.is-active-link::before {
+ background-color: $primary !important;
+}
diff --git a/assets/scss/main.scss b/assets/scss/main.scss
index 4926a6a8eb..54afb622f7 100644
--- a/assets/scss/main.scss
+++ b/assets/scss/main.scss
@@ -36,7 +36,7 @@
@import "shortcodes";
@import "swagger";
@import "support/rtl";
-
+@import "tocbot";
@if $td-enable-google-fonts {
@import url($web-font-path);
diff --git a/layouts/_partials/scripts.html b/layouts/_partials/scripts.html
index 181af6566a..33812f53de 100644
--- a/layouts/_partials/scripts.html
+++ b/layouts/_partials/scripts.html
@@ -74,6 +74,11 @@
{{ template "algolia/scripts" .Site.Params.search.algolia -}}
{{ end -}}
+
+{{ if .Site.Params.jstoc.enable -}}
+{{- partial "scripts/jstoc.html" . -}}
+{{ end -}}
+
{{ partial "hooks/body-end.html" . -}}
{{ define "algolia/scripts" -}}
diff --git a/layouts/_partials/scripts/jstoc.html b/layouts/_partials/scripts/jstoc.html
new file mode 100644
index 0000000000..4417025186
--- /dev/null
+++ b/layouts/_partials/scripts/jstoc.html
@@ -0,0 +1,44 @@
+{{ $version := .Site.Params.jstoc.version | default "latest" -}}
+
+{{ $css_url := printf "https://cdn.jsdelivr.net/npm/tocbot@%s/dist/tocbot%s.css" $version (cond hugo.IsProduction ".min" "") -}}
+{{ $cdn_url := printf "https://cdn.jsdelivr.net/npm/tocbot@%s/dist/tocbot%s.js" $version (cond hugo.IsProduction ".min" "") -}}
+
+{{ with try (resources.GetRemote $css_url) -}}
+ {{ with .Err -}}
+ {{ errorf "Could not retrieve Tocbot css file from CDN. Reason: %s." . -}}
+ {{ else with.Value -}}
+ {{ with resources.Copy (printf "css/tocbotx%s.css" (cond hugo.IsProduction ".min" "")) . }}
+ {{ $secureCSS := . | resources.Fingerprint "sha512" -}}
+
+ {{ end -}}
+ {{ end -}}
+{{ else -}}
+ {{ errorf "Invalid Tocbot version %s, could not retrieve this version from CDN." $version -}}
+{{ end -}}
+
+{{ with try (resources.GetRemote $cdn_url) -}}
+ {{ with .Err -}}
+ {{ errorf "Could not retrieve Tocbot script from CDN. Reason: %s." . -}}
+ {{ else with.Value -}}
+ {{ with resources.Copy (printf "js/tocbot%s.js" (cond hugo.IsProduction ".min" "")) . }}
+ {{ $secureJS := . | resources.Fingerprint "sha512" -}}
+
+ {{ end -}}
+ {{ end -}}
+{{ else -}}
+ {{ errorf "Invalid Tocbot version %s, could not retrieve this version from CDN." $version -}}
+{{ end -}}
+
+
+
diff --git a/userguide/content/en/docs/adding-content/lookandfeel.md b/userguide/content/en/docs/adding-content/lookandfeel.md
index d8713cb832..e3cdc2ce76 100644
--- a/userguide/content/en/docs/adding-content/lookandfeel.md
+++ b/userguide/content/en/docs/adding-content/lookandfeel.md
@@ -555,3 +555,29 @@ feature of Hugo in your configuration file, or in the front matter of the
highest-level page you want to modify.
[bs-docs]: https://getbootstrap.com/docs/
+
+## Right sidebar table of contents
+
+By default, Docsy shows the table of contents for the current page in the right sidebar using the built-in function of Hugo. You can replace that with a JavaScript-based ToC that uses the [https://tscanlin.github.io/tocbot/](Tocbot library) by setting the following in your `config.toml` file:
+
+```toml
+[params.jstoc]
+enable = true
+```
+
+By default, h2-h4 headings are included in the sidebar, which includes tips and warnings if you are using the [alert shortcode of Docsy](/docs/adding-content/shortcodes/#alert). To change that,
+provide a comma-separated list of the headings to include in the `custom_headings` parameter, for example:
+
+```toml
+[params.jstoc]
+enable = true
+custom_headings = "h2, h3"
+```
+
+Compared to the default sidebar ToC, this solution:
+
+- has a marker that shows the current location of the screen (useful for long pages)
+- shows the correct title even if the title contains a shortcode
+- shows the title in the toc even if it was included from another file
+
+
diff --git a/userguide/static/images/sidebar-toc-with-tocbot.png b/userguide/static/images/sidebar-toc-with-tocbot.png
new file mode 100644
index 0000000000..93779b674e
Binary files /dev/null and b/userguide/static/images/sidebar-toc-with-tocbot.png differ