]> git.ipfire.org Git - thirdparty/bootstrap.git/commitdiff
Docs: replace Algolia with Pagefind
authorJulien Déramond <juderamond@gmail.com>
Tue, 28 Oct 2025 18:01:55 +0000 (19:01 +0100)
committerJulien Déramond <juderamond@gmail.com>
Tue, 28 Oct 2025 18:01:55 +0000 (19:01 +0100)
package-lock.json
package.json
site/astro.config.ts
site/src/components/Search.astro [new file with mode: 0644]
site/src/components/header/Navigation.astro
site/src/plugins/algolia-plugin.js [deleted file]

index fae9ae2ef9c28b9b32b22384be00208627e31d1d..7f23d8a14116d52707834be725b49373c75dad49 100644 (file)
@@ -39,6 +39,7 @@
         "@types/prismjs": "^1.26.5",
         "astro": "^5.15.2",
         "astro-auto-import": "^0.4.5",
+        "astro-pagefind": "^1.8.5",
         "autoprefixer": "^10.4.21",
         "bundlewatch": "^0.4.1",
         "clean-css-cli": "^5.6.3",
       "dev": true,
       "license": "MIT"
     },
+    "node_modules/@pagefind/darwin-arm64": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/@pagefind/darwin-arm64/-/darwin-arm64-1.4.0.tgz",
+      "integrity": "sha512-2vMqkbv3lbx1Awea90gTaBsvpzgRs7MuSgKDxW0m9oV1GPZCZbZBJg/qL83GIUEN2BFlY46dtUZi54pwH+/pTQ==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "darwin"
+      ]
+    },
+    "node_modules/@pagefind/darwin-x64": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/@pagefind/darwin-x64/-/darwin-x64-1.4.0.tgz",
+      "integrity": "sha512-e7JPIS6L9/cJfow+/IAqknsGqEPjJnVXGjpGm25bnq+NPdoD3c/7fAwr1OXkG4Ocjx6ZGSCijXEV4ryMcH2E3A==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "darwin"
+      ]
+    },
+    "node_modules/@pagefind/default-ui": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/@pagefind/default-ui/-/default-ui-1.4.0.tgz",
+      "integrity": "sha512-wie82VWn3cnGEdIjh4YwNESyS1G6vRHwL6cNjy9CFgNnWW/PGRjsLq300xjVH5sfPFK3iK36UxvIBymtQIEiSQ==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/@pagefind/freebsd-x64": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/@pagefind/freebsd-x64/-/freebsd-x64-1.4.0.tgz",
+      "integrity": "sha512-WcJVypXSZ+9HpiqZjFXMUobfFfZZ6NzIYtkhQ9eOhZrQpeY5uQFqNWLCk7w9RkMUwBv1HAMDW3YJQl/8OqsV0Q==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "freebsd"
+      ]
+    },
+    "node_modules/@pagefind/linux-arm64": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/@pagefind/linux-arm64/-/linux-arm64-1.4.0.tgz",
+      "integrity": "sha512-PIt8dkqt4W06KGmQjONw7EZbhDF+uXI7i0XtRLN1vjCUxM9vGPdtJc2mUyVPevjomrGz5M86M8bqTr6cgDp1Uw==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/@pagefind/linux-x64": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/@pagefind/linux-x64/-/linux-x64-1.4.0.tgz",
+      "integrity": "sha512-z4oddcWwQ0UHrTHR8psLnVlz6USGJ/eOlDPTDYZ4cI8TK8PgwRUPQZp9D2iJPNIPcS6Qx/E4TebjuGJOyK8Mmg==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/@pagefind/windows-x64": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/@pagefind/windows-x64/-/windows-x64-1.4.0.tgz",
+      "integrity": "sha512-NkT+YAdgS2FPCn8mIA9bQhiBs+xmniMGq1LFPDhcFn0+2yIUEiIG06t7bsZlhdjknEQRTSdT7YitP6fC5qwP0g==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "win32"
+      ]
+    },
     "node_modules/@pkgjs/parseargs": {
       "version": "0.11.0",
       "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
         "node": ">=14"
       }
     },
+    "node_modules/@polka/url": {
+      "version": "1.0.0-next.29",
+      "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.29.tgz",
+      "integrity": "sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==",
+      "dev": true,
+      "license": "MIT"
+    },
     "node_modules/@popperjs/core": {
       "version": "2.11.8",
       "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz",
         "astro": "^2.0.0 || ^3.0.0-beta || ^4.0.0-beta || ^5.0.0-beta"
       }
     },
+    "node_modules/astro-pagefind": {
+      "version": "1.8.5",
+      "resolved": "https://registry.npmjs.org/astro-pagefind/-/astro-pagefind-1.8.5.tgz",
+      "integrity": "sha512-CVhKKA9bTQ7hLsHk9KTNDzOdgR4EI04gn0mjDGfnXzaHx7rL92YkNpFM5AoFl9NWmOUbaIFC2DN7Yvs/ZFPRdA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@pagefind/default-ui": "^1.2.0",
+        "pagefind": "^1.2.0",
+        "sirv": "^3.0.0"
+      },
+      "peerDependencies": {
+        "astro": "^2.0.4 || ^3 || ^4 || ^5"
+      }
+    },
     "node_modules/astro/node_modules/semver": {
       "version": "7.7.3",
       "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz",
       "dev": true,
       "license": "MIT"
     },
+    "node_modules/pagefind": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/pagefind/-/pagefind-1.4.0.tgz",
+      "integrity": "sha512-z2kY1mQlL4J8q5EIsQkLzQjilovKzfNVhX8De6oyE6uHpfFtyBaqUpcl/XzJC/4fjD8vBDyh1zolimIcVrCn9g==",
+      "dev": true,
+      "license": "MIT",
+      "bin": {
+        "pagefind": "lib/runner/bin.cjs"
+      },
+      "optionalDependencies": {
+        "@pagefind/darwin-arm64": "1.4.0",
+        "@pagefind/darwin-x64": "1.4.0",
+        "@pagefind/freebsd-x64": "1.4.0",
+        "@pagefind/linux-arm64": "1.4.0",
+        "@pagefind/linux-x64": "1.4.0",
+        "@pagefind/windows-x64": "1.4.0"
+      }
+    },
     "node_modules/pako": {
       "version": "0.2.9",
       "resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz",
         "node": ">=10"
       }
     },
+    "node_modules/sirv": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/sirv/-/sirv-3.0.2.tgz",
+      "integrity": "sha512-2wcC/oGxHis/BoHkkPwldgiPSYcpZK3JU28WoMVv55yHJgcZ8rlXvuG9iZggz+sU1d4bRgIGASwyWqjxu3FM0g==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@polka/url": "^1.0.0-next.24",
+        "mrmime": "^2.0.0",
+        "totalist": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=18"
+      }
+    },
     "node_modules/sisteransi": {
       "version": "1.0.5",
       "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz",
         "node": ">=0.6"
       }
     },
+    "node_modules/totalist": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz",
+      "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=6"
+      }
+    },
     "node_modules/touch": {
       "version": "3.1.1",
       "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.1.tgz",
index 3101f96089ac3dc5b215ef831c33351ef742ed39..430a4f9d331e03795e8ce9c30b3ddfb31dba9040 100644 (file)
     "@types/prismjs": "^1.26.5",
     "astro": "^5.15.2",
     "astro-auto-import": "^0.4.5",
+    "astro-pagefind": "^1.8.5",
     "autoprefixer": "^10.4.21",
     "bundlewatch": "^0.4.1",
     "clean-css-cli": "^5.6.3",
index 400330f4a4cd67dc887aa79eafbb33a8a77d5390..3ec66cb6f1049529f6e5f76fcf5b7d56005035d7 100644 (file)
@@ -1,8 +1,8 @@
 import { defineConfig } from 'astro/config'
+import pagefind from 'astro-pagefind';
 
 import { bootstrap } from './src/libs/astro'
 import { getConfig } from './src/libs/config'
-import { algoliaPlugin } from './src/plugins/algolia-plugin'
 import { stackblitzPlugin } from './src/plugins/stackblitz-plugin'
 
 const isDev = process.env.NODE_ENV === 'development'
@@ -21,13 +21,16 @@ export default defineConfig({
   build: {
     assets: `docs/${getConfig().docs_version}/assets`
   },
-  integrations: [bootstrap()],
+  integrations: [
+    bootstrap(),
+    pagefind(),
+  ],
   markdown: {
     smartypants: false,
     syntaxHighlight: 'prism'
   },
   site,
   vite: {
-    plugins: [algoliaPlugin(), stackblitzPlugin()]
+    plugins: [stackblitzPlugin()]
   }
 })
diff --git a/site/src/components/Search.astro b/site/src/components/Search.astro
new file mode 100644 (file)
index 0000000..0caf83f
--- /dev/null
@@ -0,0 +1,115 @@
+---
+import Search from "astro-pagefind/components/Search";
+export const prerender = false;
+const q = Astro.url.searchParams.get("q") ?? undefined;
+---
+
+<div class="wrapper" style="z-index: 5">
+  <Search id="search" uiOptions={{ showImages: false }} query={q} />
+</div>
+
+<style lang="scss">
+.wrapper {
+  --pagefind-ui-background: var(--bs-body-bg);
+  --pagefind-ui-text: var(--bs-body-color);
+  --pagefind-ui-border: var(--bs-border-color);
+  --search-height: 2.25rem;
+  --search-width: min(40vw, 32rem);
+
+  background: var(--bs-body-bg);
+  box-sizing: border-box;
+  color: var(--bs-body-color);
+  height: 2.5rem;
+  left: calc(0.5 * (100vw - var(--search-width)));
+  max-width: var(--search-width);
+  padding-inline: 10px;
+  position: absolute;
+  top: 0.75rem;
+  width: 100%;
+  z-index: 20;
+}
+</style>
+
+
+<style is:global lang="scss">
+#search .pagefind-ui__button {
+  color: var(--bs-body-color);
+}
+
+#search .pagefind-ui__drawer {
+  background: var(--bs-body-bg);
+  border-block-end: 1px solid var(--bs-border-color);
+  border-end-end-radius: 10px;
+  border-end-start-radius: 10px;
+  border-inline: 1px solid var(--bs-border-color);
+  box-sizing: border-box;
+  padding-inline: 10px;
+  padding-block-end: 10px;
+}
+
+#search .pagefind-ui__form {
+  &::before {
+    content: '';
+    top: 0.75rem;
+  }
+}
+
+#search .pagefind-ui__message {
+  font-size: 12px;
+  font-weight: 400;
+  opacity: 0.8;
+  padding-block-end: 0;
+  text-align: center;
+}
+
+#search .pagefind-ui__result {
+  padding-block: 10px;
+
+  &:last-of-type {
+    border-block-end: 0;
+    padding-block-end: 0;
+  }
+}
+
+#search .pagefind-ui__result-excerpt {
+  font-size: 12px;
+  line-height: 1.25;
+}
+
+#search .pagefind-ui__result-inner {
+  margin-block-start: 0;
+}
+
+#search .pagefind-ui__result-link {
+  color: var(--bs-body-emphasis);
+}
+
+#search .pagefind-ui__result-title {
+  font-size: 16px;
+}
+
+#search .pagefind-ui__results {
+  margin-block-start: 10px;
+
+  &:empty {
+    margin-block-start: 0;
+  }
+}
+
+#search .pagefind-ui__results-area {
+  margin-block-start: 0;
+}
+
+#search .pagefind-ui__search-input {
+  color: var(--bs-body-color);
+  font-size: 16px;
+  font-weight: 400;
+  height: var(--search-height);
+  outline: 1px solid var(--bs-body-emphasis);
+}
+
+#search .pagefind-ui__search-clear {
+  height: var(--search-height);
+  top: 0;
+}
+</style>
index b1ebe458b21cc4179b5ce78c8f5c361e8c7ca268..220c328c58a34b4f0ddcda07c9d032dc8f874b95 100644 (file)
@@ -11,6 +11,7 @@ import OpenCollectiveIcon from '@components/icons/OpenCollectiveIcon.astro'
 import XIcon from '@components/icons/XIcon.astro'
 import Versions from '@components/header/Versions.astro'
 import ThemeToggler from '@layouts/partials/ThemeToggler.astro'
+import Search from "@components/Search.astro";
 
 interface Props {
   addedIn?: CollectionEntry<'docs'>['data']['added']
@@ -47,7 +48,7 @@ const { addedIn, layout, title } = Astro.props
     </a>
 
     <div class="d-flex">
-      <div class="bd-search" id="docsearch" data-bd-docs-version={getConfig().docs_version}></div>
+      <Search />
 
       <button
         class="navbar-toggler d-flex d-lg-none order-3 p-2"
diff --git a/site/src/plugins/algolia-plugin.js b/site/src/plugins/algolia-plugin.js
deleted file mode 100644 (file)
index 3481140..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-import { getConfig } from '../libs/config.ts'
-
-/**
- * Vite plugin to replace placeholder values in search.js with actual configuration values
- */
-export function algoliaPlugin() {
-  const config = getConfig()
-
-  return {
-    name: 'algolia-config-replacer',
-    transform(code, id) {
-      if (id.includes('search.js')) {
-        return code
-          .replace(/__API_KEY__/g, config.algolia.api_key)
-          .replace(/__INDEX_NAME__/g, config.algolia.index_name)
-          .replace(/__APP_ID__/g, config.algolia.app_id)
-      }
-
-      return code
-    }
-  }
-}