mirror of
https://github.com/ChenQihan666/MyBlog-Next.git
synced 2026-08-14 07:33:07 +08:00
feat!: add pagefind for static search (#458)
Replace React with pagefind for static site search
This commit is contained in:
@@ -22,3 +22,7 @@ pnpm-debug.log*
|
|||||||
|
|
||||||
# jetbrains setting folder
|
# jetbrains setting folder
|
||||||
.idea/
|
.idea/
|
||||||
|
|
||||||
|
# pagefind
|
||||||
|
|
||||||
|
public/pagefind
|
||||||
+3
-1
@@ -4,7 +4,7 @@
|
|||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "astro dev",
|
"dev": "astro dev",
|
||||||
"build": "astro check && astro build",
|
"build": "astro check && astro build && pagefind --site dist && cp -r dist/pagefind public/",
|
||||||
"preview": "astro preview",
|
"preview": "astro preview",
|
||||||
"astro": "astro",
|
"astro": "astro",
|
||||||
"format:check": "prettier --check .",
|
"format:check": "prettier --check .",
|
||||||
@@ -27,12 +27,14 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@astrojs/check": "^0.9.4",
|
"@astrojs/check": "^0.9.4",
|
||||||
|
"@pagefind/default-ui": "^1.3.0",
|
||||||
"@tailwindcss/typography": "^0.5.16",
|
"@tailwindcss/typography": "^0.5.16",
|
||||||
"@types/lodash.kebabcase": "^4.1.9",
|
"@types/lodash.kebabcase": "^4.1.9",
|
||||||
"@typescript-eslint/parser": "^8.25.0",
|
"@typescript-eslint/parser": "^8.25.0",
|
||||||
"eslint": "^9.21.0",
|
"eslint": "^9.21.0",
|
||||||
"eslint-plugin-astro": "^1.3.1",
|
"eslint-plugin-astro": "^1.3.1",
|
||||||
"globals": "^16.0.0",
|
"globals": "^16.0.0",
|
||||||
|
"pagefind": "^1.3.0",
|
||||||
"prettier": "^3.5.2",
|
"prettier": "^3.5.2",
|
||||||
"prettier-plugin-astro": "^0.14.1",
|
"prettier-plugin-astro": "^0.14.1",
|
||||||
"prettier-plugin-tailwindcss": "^0.6.11",
|
"prettier-plugin-tailwindcss": "^0.6.11",
|
||||||
|
|||||||
Generated
+63
@@ -48,6 +48,9 @@ importers:
|
|||||||
'@astrojs/check':
|
'@astrojs/check':
|
||||||
specifier: ^0.9.4
|
specifier: ^0.9.4
|
||||||
version: 0.9.4(prettier-plugin-astro@0.14.1)(prettier@3.5.2)(typescript@5.7.3)
|
version: 0.9.4(prettier-plugin-astro@0.14.1)(prettier@3.5.2)(typescript@5.7.3)
|
||||||
|
'@pagefind/default-ui':
|
||||||
|
specifier: ^1.3.0
|
||||||
|
version: 1.3.0
|
||||||
'@tailwindcss/typography':
|
'@tailwindcss/typography':
|
||||||
specifier: ^0.5.16
|
specifier: ^0.5.16
|
||||||
version: 0.5.16(tailwindcss@4.0.8)
|
version: 0.5.16(tailwindcss@4.0.8)
|
||||||
@@ -66,6 +69,9 @@ importers:
|
|||||||
globals:
|
globals:
|
||||||
specifier: ^16.0.0
|
specifier: ^16.0.0
|
||||||
version: 16.0.0
|
version: 16.0.0
|
||||||
|
pagefind:
|
||||||
|
specifier: ^1.3.0
|
||||||
|
version: 1.3.0
|
||||||
prettier:
|
prettier:
|
||||||
specifier: ^3.5.2
|
specifier: ^3.5.2
|
||||||
version: 3.5.2
|
version: 3.5.2
|
||||||
@@ -496,6 +502,34 @@ packages:
|
|||||||
'@oslojs/encoding@1.1.0':
|
'@oslojs/encoding@1.1.0':
|
||||||
resolution: {integrity: sha512-70wQhgYmndg4GCPxPPxPGevRKqTIJ2Nh4OkiMWmDAVYsTQ+Ta7Sq+rPevXyXGdzr30/qZBnyOalCszoMxlyldQ==}
|
resolution: {integrity: sha512-70wQhgYmndg4GCPxPPxPGevRKqTIJ2Nh4OkiMWmDAVYsTQ+Ta7Sq+rPevXyXGdzr30/qZBnyOalCszoMxlyldQ==}
|
||||||
|
|
||||||
|
'@pagefind/darwin-arm64@1.3.0':
|
||||||
|
resolution: {integrity: sha512-365BEGl6ChOsauRjyVpBjXybflXAOvoMROw3TucAROHIcdBvXk9/2AmEvGFU0r75+vdQI4LJdJdpH4Y6Yqaj4A==}
|
||||||
|
cpu: [arm64]
|
||||||
|
os: [darwin]
|
||||||
|
|
||||||
|
'@pagefind/darwin-x64@1.3.0':
|
||||||
|
resolution: {integrity: sha512-zlGHA23uuXmS8z3XxEGmbHpWDxXfPZ47QS06tGUq0HDcZjXjXHeLG+cboOy828QIV5FXsm9MjfkP5e4ZNbOkow==}
|
||||||
|
cpu: [x64]
|
||||||
|
os: [darwin]
|
||||||
|
|
||||||
|
'@pagefind/default-ui@1.3.0':
|
||||||
|
resolution: {integrity: sha512-CGKT9ccd3+oRK6STXGgfH+m0DbOKayX6QGlq38TfE1ZfUcPc5+ulTuzDbZUnMo+bubsEOIypm4Pl2iEyzZ1cNg==}
|
||||||
|
|
||||||
|
'@pagefind/linux-arm64@1.3.0':
|
||||||
|
resolution: {integrity: sha512-8lsxNAiBRUk72JvetSBXs4WRpYrQrVJXjlRRnOL6UCdBN9Nlsz0t7hWstRk36+JqHpGWOKYiuHLzGYqYAqoOnQ==}
|
||||||
|
cpu: [arm64]
|
||||||
|
os: [linux]
|
||||||
|
|
||||||
|
'@pagefind/linux-x64@1.3.0':
|
||||||
|
resolution: {integrity: sha512-hAvqdPJv7A20Ucb6FQGE6jhjqy+vZ6pf+s2tFMNtMBG+fzcdc91uTw7aP/1Vo5plD0dAOHwdxfkyw0ugal4kcQ==}
|
||||||
|
cpu: [x64]
|
||||||
|
os: [linux]
|
||||||
|
|
||||||
|
'@pagefind/windows-x64@1.3.0':
|
||||||
|
resolution: {integrity: sha512-BR1bIRWOMqkf8IoU576YDhij1Wd/Zf2kX/kCI0b2qzCKC8wcc2GQJaaRMCpzvCCrmliO4vtJ6RITp/AnoYUUmQ==}
|
||||||
|
cpu: [x64]
|
||||||
|
os: [win32]
|
||||||
|
|
||||||
'@pkgr/core@0.1.1':
|
'@pkgr/core@0.1.1':
|
||||||
resolution: {integrity: sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==}
|
resolution: {integrity: sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==}
|
||||||
engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0}
|
engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0}
|
||||||
@@ -1918,6 +1952,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==}
|
resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==}
|
||||||
engines: {node: '>=6'}
|
engines: {node: '>=6'}
|
||||||
|
|
||||||
|
pagefind@1.3.0:
|
||||||
|
resolution: {integrity: sha512-8KPLGT5g9s+olKMRTU9LFekLizkVIu9tes90O1/aigJ0T5LmyPqTzGJrETnSw3meSYg58YH7JTzhTTW/3z6VAw==}
|
||||||
|
hasBin: true
|
||||||
|
|
||||||
pako@0.2.9:
|
pako@0.2.9:
|
||||||
resolution: {integrity: sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA==}
|
resolution: {integrity: sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA==}
|
||||||
|
|
||||||
@@ -3074,6 +3112,23 @@ snapshots:
|
|||||||
|
|
||||||
'@oslojs/encoding@1.1.0': {}
|
'@oslojs/encoding@1.1.0': {}
|
||||||
|
|
||||||
|
'@pagefind/darwin-arm64@1.3.0':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@pagefind/darwin-x64@1.3.0':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@pagefind/default-ui@1.3.0': {}
|
||||||
|
|
||||||
|
'@pagefind/linux-arm64@1.3.0':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@pagefind/linux-x64@1.3.0':
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@pagefind/windows-x64@1.3.0':
|
||||||
|
optional: true
|
||||||
|
|
||||||
'@pkgr/core@0.1.1': {}
|
'@pkgr/core@0.1.1': {}
|
||||||
|
|
||||||
'@resvg/resvg-js-android-arm-eabi@2.6.2':
|
'@resvg/resvg-js-android-arm-eabi@2.6.2':
|
||||||
@@ -4771,6 +4826,14 @@ snapshots:
|
|||||||
|
|
||||||
p-try@2.2.0: {}
|
p-try@2.2.0: {}
|
||||||
|
|
||||||
|
pagefind@1.3.0:
|
||||||
|
optionalDependencies:
|
||||||
|
'@pagefind/darwin-arm64': 1.3.0
|
||||||
|
'@pagefind/darwin-x64': 1.3.0
|
||||||
|
'@pagefind/linux-arm64': 1.3.0
|
||||||
|
'@pagefind/linux-x64': 1.3.0
|
||||||
|
'@pagefind/windows-x64': 1.3.0
|
||||||
|
|
||||||
pako@0.2.9: {}
|
pako@0.2.9: {}
|
||||||
|
|
||||||
parent-module@1.0.1:
|
parent-module@1.0.1:
|
||||||
|
|||||||
@@ -74,6 +74,7 @@ const nextPost =
|
|||||||
"mx-auto w-full max-w-3xl px-4 pb-12",
|
"mx-auto w-full max-w-3xl px-4 pb-12",
|
||||||
{ "mt-8": !SITE.showBackButton },
|
{ "mt-8": !SITE.showBackButton },
|
||||||
]}
|
]}
|
||||||
|
data-pagefind-body
|
||||||
>
|
>
|
||||||
<h1
|
<h1
|
||||||
transition:name={slugifyStr(title)}
|
transition:name={slugifyStr(title)}
|
||||||
@@ -119,7 +120,7 @@ const nextPost =
|
|||||||
<hr class="my-6 border-dashed" />
|
<hr class="my-6 border-dashed" />
|
||||||
|
|
||||||
<!-- Previous/Next Post Buttons -->
|
<!-- Previous/Next Post Buttons -->
|
||||||
<div class="grid grid-cols-1 gap-6 sm:grid-cols-2">
|
<div data-pagefind-ignore class="grid grid-cols-1 gap-6 sm:grid-cols-2">
|
||||||
{
|
{
|
||||||
prevPost && (
|
prevPost && (
|
||||||
<a
|
<a
|
||||||
|
|||||||
+118
-1
@@ -1,15 +1,132 @@
|
|||||||
---
|
---
|
||||||
|
import "@pagefind/default-ui/css/ui.css";
|
||||||
import Main from "@/layouts/Main.astro";
|
import Main from "@/layouts/Main.astro";
|
||||||
import Layout from "@/layouts/Layout.astro";
|
import Layout from "@/layouts/Layout.astro";
|
||||||
import Header from "@/components/Header.astro";
|
import Header from "@/components/Header.astro";
|
||||||
import Footer from "@/components/Footer.astro";
|
import Footer from "@/components/Footer.astro";
|
||||||
import { SITE } from "@/config";
|
import { SITE } from "@/config";
|
||||||
|
|
||||||
|
const backUrl = SITE.showBackButton ? `${Astro.url.pathname}` : "/";
|
||||||
---
|
---
|
||||||
|
|
||||||
<Layout title={`Search | ${SITE.title}`}>
|
<Layout title={`Search | ${SITE.title}`}>
|
||||||
<Header />
|
<Header />
|
||||||
<Main pageTitle="Search" pageDesc="Search any article ...">
|
<Main pageTitle="Search" pageDesc="Search any article ...">
|
||||||
<!-- Search bar -->
|
<div id="pagefind-search" transition:persist data-backurl={backUrl}></div>
|
||||||
</Main>
|
</Main>
|
||||||
<Footer />
|
<Footer />
|
||||||
</Layout>
|
</Layout>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
function initSearch() {
|
||||||
|
const pageFindSearch: HTMLElement | null =
|
||||||
|
document.querySelector("#pagefind-search");
|
||||||
|
|
||||||
|
if (!pageFindSearch) return;
|
||||||
|
|
||||||
|
const params = new URLSearchParams(window.location.search);
|
||||||
|
|
||||||
|
const onIdle = window.requestIdleCallback || (cb => setTimeout(cb, 1));
|
||||||
|
|
||||||
|
onIdle(async () => {
|
||||||
|
// @ts-expect-error — Missing types for @pagefind/default-ui package.
|
||||||
|
const { PagefindUI } = await import("@pagefind/default-ui");
|
||||||
|
|
||||||
|
// Display warning inn dev mode
|
||||||
|
if (import.meta.env.DEV) {
|
||||||
|
pageFindSearch.innerHTML = `
|
||||||
|
<div class="bg-muted/75 rounded p-4 space-y-4 mb-4">
|
||||||
|
<p><strong>DEV mode Warning! </strong>You need to build the project at least once to see the search results during development.</p>
|
||||||
|
<code class="block bg-black text-white px-2 py-1 rounded">pnpm run build</code>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Init pagefind ui
|
||||||
|
const search = new PagefindUI({
|
||||||
|
element: "#pagefind-search",
|
||||||
|
showSubResults: true,
|
||||||
|
showImages: false,
|
||||||
|
processTerm: function (term: string) {
|
||||||
|
params.set("q", term); // Update the `q` parameter in the URL
|
||||||
|
history.replaceState(history.state, "", "?" + params.toString()); // Push the new URL without reloading
|
||||||
|
|
||||||
|
const backUrl = pageFindSearch?.dataset?.backurl;
|
||||||
|
sessionStorage.setItem("backUrl", backUrl + "?" + params.toString());
|
||||||
|
|
||||||
|
return term;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// If search param exists (eg: search?q=astro), trigger search
|
||||||
|
const query = params.get("q");
|
||||||
|
if (query) {
|
||||||
|
search.triggerSearch(query);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset search param if search input is cleared
|
||||||
|
const searchInput = document.querySelector(".pagefind-ui__search-input");
|
||||||
|
const clearButton = document.querySelector(".pagefind-ui__search-clear");
|
||||||
|
searchInput?.addEventListener("input", resetSearchParam);
|
||||||
|
clearButton?.addEventListener("click", resetSearchParam);
|
||||||
|
|
||||||
|
function resetSearchParam(e: Event) {
|
||||||
|
if ((e.target as HTMLInputElement)?.value.trim() === "") {
|
||||||
|
history.replaceState(history.state, "", window.location.pathname);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
document.addEventListener("astro:after-swap", initSearch);
|
||||||
|
initSearch();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style is:global>
|
||||||
|
#pagefind-search {
|
||||||
|
--pagefind-ui-font: var(--font-mono);
|
||||||
|
--pagefind-ui-text: var(--foreground);
|
||||||
|
--pagefind-ui-background: var(--background);
|
||||||
|
--pagefind-ui-border: var(--border);
|
||||||
|
--pagefind-ui-primary: var(--accent);
|
||||||
|
--pagefind-ui-tag: var(--background);
|
||||||
|
--pagefind-ui-border-radius: 0.375rem;
|
||||||
|
--pagefind-ui-border-width: 1px;
|
||||||
|
--pagefind-ui-image-border-radius: 8px;
|
||||||
|
--pagefind-ui-image-box-ratio: 3 / 2;
|
||||||
|
|
||||||
|
form::before {
|
||||||
|
background-color: var(--foreground);
|
||||||
|
}
|
||||||
|
|
||||||
|
input {
|
||||||
|
font-weight: 400;
|
||||||
|
border: 1px solid var(--border);
|
||||||
|
}
|
||||||
|
|
||||||
|
input:focus-visible {
|
||||||
|
outline: 1px solid var(--accent);
|
||||||
|
}
|
||||||
|
|
||||||
|
.pagefind-ui__result-title a {
|
||||||
|
color: var(--accent);
|
||||||
|
outline-offset: 1px;
|
||||||
|
outline-color: var(--accent);
|
||||||
|
}
|
||||||
|
|
||||||
|
.pagefind-ui__result-title a:focus-visible,
|
||||||
|
.pagefind-ui__search-clear:focus-visible {
|
||||||
|
text-decoration-line: none;
|
||||||
|
outline-width: 2px;
|
||||||
|
outline-style: dashed;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pagefind-ui__result:last-of-type {
|
||||||
|
border-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pagefind-ui__result-nested .pagefind-ui__result-link:before {
|
||||||
|
font-family: system-ui;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"extends": "astro/tsconfigs/strict",
|
"extends": "astro/tsconfigs/strict",
|
||||||
"include": [".astro/types.d.ts", "**/*"],
|
"include": [".astro/types.d.ts", "**/*"],
|
||||||
"exclude": ["dist"],
|
"exclude": ["dist", "public/pagefind"],
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"baseUrl": ".",
|
"baseUrl": ".",
|
||||||
"paths": {
|
"paths": {
|
||||||
|
|||||||
Reference in New Issue
Block a user