Open kamoshi opened 1 year ago
π Hey @kamoshi
This is a good suggestion, I'll look into whether it's viable for us. I believe early models of Pagefind had a slightly more bespoke search bundle per-site, but now the version string is the only dynamic content, so in theory that file can be distributed elsewhere.
There are a couple of reasons I haven't pursued this yet:
/_pagefind/pagefind.js
uses its own import path at runtime to locate the /_pagefind/pagefind-entry.json
+ the rest of the wasm files and search bundle. This has been handy for lowering the config barrier, but isn't that big of a deal in the grand scheme of thingsIn saying that, those aren't good enough reasons to not do it at all! 1.
isn't a blocker, but will just require some careful documentation. Regarding 2.
, perhaps a solution is publishing a wrapper package around the JS client to NPM. This would give you your typescript definitions and nice DX integrations, but ultimately under the hood will import("/_pagefind/pagefind.js")
to interface with Pagefind, so that the WASM communication doesn't get baked into the NPM version. It should be transparent to the end-user, unless Vite digs deep and complains about the inner import π€
Let me know your thoughts on that π
Just a +1 for me for @kamoshi 's feature requests, I think both an NPM package and types would greatly improve adoption and DX!
I'd love too!
Just in case anyone is having the same issue, I'm using pagefind with the node api in a Remix + vite project and I had to use this syntax to be able to import:
export interface Pagefind {
search: (query: string) => Promise<PagefindResponse>;
}
export interface PagefindResponse {
results: PagefindResult[];
}
export interface PagefindResult {
id: string;
data: () => Promise<PagefindDocument>;
}
export interface PagefindDocument {
url: string;
raw_url: string;
excerpt: string;
// ... whatever else
}
declare global {
interface Window {
pagefind: Pagefind;
}
}
export async function importPagefind(): Promise<Pagefind> {
const url = new URL("/pagefind/pagefind.js", import.meta.url).href;
return await import(/* @vite-ignore */ url);
}
And then load it with a useEffect
useEffect(() => {
async function loadPagefind() {
if (typeof window.pagefind === "undefined") {
try {
window.pagefind = await importPagefind();
} catch (e) {
window.pagefind = {
search: async () => ({ results: [] }),
};
}
}
}
loadPagefind();
}, []);
This will look for pagefind in the public directly so this works for both dev and production but you need to build pagefind first.
I've found that some of the biggest headaches while using Pagefind in a JS framework come from the fact that:
pagefind
package. This makes it much harder to use Pagefind with build tools like Vite.@types/pagefind
package or have types included. It would make it easier to use the JS client even when not using TypeScript.For example, I used Pagefind JS client in Solidjs via Astro, which uses Vite. The way I went about it was that I first wrote my own rudimentary types:
Then I had to import Pagefind in a way that would avoid Vite headaches:
After doing all this Pagefind does work correctly, but I'm getting a warning: