diff --git a/data/versions.yml b/data/versions.yml
index f7d6363f23c8..2b19762f6202 100644
--- a/data/versions.yml
+++ b/data/versions.yml
@@ -3,3 +3,11 @@ main: "1.26"
# The version of Istio currently documented in preliminary.istio.io
preliminary: "1.27"
+
+supported_versions:
+ - version: "latest"
+ - version: "v1.25"
+ - version: "v1.24"
+ - version: "v1.23"
+ - version: "v1.22"
+ - version: "v1.21"
\ No newline at end of file
diff --git a/layouts/_default/search.html b/layouts/_default/search.html
index 306e8713ee0d..ef17566665eb 100644
--- a/layouts/_default/search.html
+++ b/layouts/_default/search.html
@@ -1,59 +1,41 @@
-{{ define "main" }}
-
-{{ partial "primary_top.html" . }}
-
-
-
-
- {{ if .Site.Data.args.archive }}
-
- {{ else }}
-
- {{ end }}
-
-
-
-
-{{ .Content }}
-
-{{ partial "primary_bottom.html" . }}
-
+{{ define "main" }}
+
+{{ partial "primary_top.html" . }}
+
+
+
+ {{ $languages := .Site.Data.args.supported_languages }}
+ {{ $versions := .Site.Data.versions.supported_versions }}
+
+
+
+
+
+
+
+
+
+
+
Loading results...
+
+
+
+
+
+{{ .Content }}
+
+{{ partial "primary_bottom.html" . }}
+
{{ end }}
\ No newline at end of file
diff --git a/layouts/partials/header.html b/layouts/partials/header.html
index cc4107465b0f..1ac7522d9ff9 100644
--- a/layouts/partials/header.html
+++ b/layouts/partials/header.html
@@ -55,19 +55,35 @@
-
+
+
diff --git a/scripts/gen_site.sh b/scripts/gen_site.sh
index 73ba9cb3cfe9..52b56158c192 100755
--- a/scripts/gen_site.sh
+++ b/scripts/gen_site.sh
@@ -40,6 +40,7 @@ babel --source-maps --minified --no-comments --presets minify \
tmp/js/callToAction.js \
tmp/js/events.js \
tmp/js/faq.js \
+ tmp/js/search.js \
--out-file generated/js/all.min.js
babel --source-maps --minified --no-comments --presets minify \
diff --git a/src/ts/search.js b/src/ts/search.js
new file mode 100644
index 000000000000..4c59c44d3aad
--- /dev/null
+++ b/src/ts/search.js
@@ -0,0 +1,116 @@
+const appId = '95IG3UJ1LV';
+const apiKey = '23827432dd1f4c529eece856289a421c';
+const indexName = 'istio';
+
+const searchClient = algoliasearch(appId, apiKey);
+const index = searchClient.initIndex(indexName);
+
+function getParameterByName(name, url = window.location.href) {
+ name = name.replace(/[\[\]]/g, "\\$&");
+ const regex = new RegExp("[?&]" + name + "(=([^]*)|&|#|$)");
+ const results = regex.exec(url);
+ if (!results) return null;
+ if (!results[2]) return '';
+ return decodeURIComponent(results[2].replace(/\+/g, " "));
+}
+
+function extractVersionAndLangFromPath() {
+ const pathParts = window.location.pathname.split('/');
+ let version = 'latest';
+ let lang = 'en';
+
+ for (const part of pathParts) {
+ if (/^v[0-9.]+$/.test(part) || part === 'latest') {
+ version = part;
+ } else if (/^[a-z]{2}(-[a-z]{2})?$/.test(part)) {
+ lang = part;
+ }
+ }
+
+ return { version, lang };
+}
+
+function updateURLParam(param, value) {
+ const url = new URL(window.location.href);
+ url.searchParams.set(param, value);
+ window.history.pushState({}, '', url);
+}
+
+const query = getParameterByName('q') || '';
+let page = parseInt(getParameterByName('page')) || 0;
+const hitsPerPage = 10;
+
+const { version, lang } = extractVersionAndLangFromPath();
+
+// Set default dropdowns
+window.addEventListener('DOMContentLoaded', () => {
+ document.getElementById('version-filter').value = version;
+ document.getElementById('lang-filter').value = lang;
+
+ document.getElementById('search-query-header').innerHTML =
+ `Search results for "${query}"
`;
+
+ function runSearch() {
+ const selectedVersion = document.getElementById('version-filter').value;
+ const selectedLang = document.getElementById('lang-filter').value;
+
+ index.search(query, {
+ hitsPerPage,
+ page,
+ facetFilters: [
+ [`lang:${selectedLang}`],
+ [`version:${selectedVersion}`]
+ ]
+ }).then(({ hits, nbPages }) => {
+ const container = document.getElementById('search-results');
+ if (hits.length === 0) {
+ container.innerHTML = `No results found for "${query}".
`;
+ document.getElementById('pagination-controls').style.display = 'none';
+ return;
+ }
+
+ container.innerHTML = hits.map(hit => {
+ const title = hit.hierarchy?.lvl1 || '(No Title)';
+ const subtitle = hit.hierarchy?.lvl2 ? ` > ${hit.hierarchy.lvl2}` : '';
+ const fullUrl = hit.anchor ? `${hit.url_without_anchor}#${hit.anchor}` : hit.url;
+
+ return `
+
+ `;
+ }).join('');
+ document.getElementById('pagination-controls').style.display = 'flex';
+ document.getElementById('page-info').textContent = `Page ${page + 1} of ${nbPages}`;
+ document.getElementById('prev-page').disabled = page <= 0;
+ document.getElementById('next-page').disabled = page + 1 >= nbPages;
+ }).catch(err => {
+ document.getElementById('search-results').innerHTML = `Error fetching results: ${err.message}
`;
+ });
+ }
+
+ document.getElementById('prev-page').addEventListener('click', () => {
+ if (page > 0) {
+ page--;
+ updateURLParam('page', page);
+ runSearch();
+ }
+ });
+
+ document.getElementById('next-page').addEventListener('click', () => {
+ page++;
+ updateURLParam('page', page);
+ runSearch();
+ });
+
+ document.getElementById('version-filter').addEventListener('change', runSearch);
+ document.getElementById('lang-filter').addEventListener('change', runSearch);
+
+ runSearch();
+});