shishkin / astro-pagefind

Astro integration for Pagefind static site search.
MIT License
267 stars 15 forks source link

Use in Astro SSR sites? #54

Open shah opened 1 year ago

shah commented 1 year ago

Great integration @shishkin! We are using Astro 3.0 in SSR mode with many Markdown pages. Does your astro-pagefind integration work with SSR pages?

shishkin commented 1 year ago

Thanks @shah. The extension doesn't work with SSR at the moment because it runs pagefind CLI index on the Astro static HTML output. Just curious why you choose SSR over SSG if your content is in static Markdown files?

shah commented 1 year ago

Good question @shishkin - we have about 50% of our site dynamic and the other 50% is Markdown -- we started in SSG with some islands support and then tried hybrid, but our use case is easier to implement with full SSR. If you have any guidance for how to use Pagefind with SSR (knowing that indexing is required) we'd love those tips/tricks.

shishkin commented 1 year ago

You might want to try and use pagefind Node.JS API to index content dynamically. I didn't use it myself and am not sure what obstacles it may present. If you get it to work, it would be a great addition to this extension.

shah commented 1 year ago

Agreed @shishkin that's that API we're planning to use if there was not any other Astro-specific solution :-). Thanks!

ColeTownsend commented 3 months ago

@shishkin @shah was able to get the pagefind Node.JS api working.

Rough example

import path from "path";

function pagefindIntegration() {
    return {
        name: "pagefind",
        hooks: {
            "astro:build:done": async () => {
                // Create a new Pagefind index
                const { index } = await pagefind.createIndex({
                    forceLanguage: "en", // Set the language to 'en'
                    verbose: true, // Enable verbose output
                });

                const { items } = await getAllItems()

                for (const item of items) {
                    const { errors } = await index.addCustomRecord({
                        url: generateUrl(item.slug),
                        content: item.description,
                        meta: {
                            title: item.title,
                            category:  item.category,
                            image: item.imageUrl,
                        },
                        language: "en",
                        filters: {
                            tags: item.tags?.map((tag) => tag.name),
                        },
                    });

                    if (errors.length > 0) {
                        console.error(`Errors occurred while adding the record for ${item.name}:`, errors);
                    } else {
                        console.log(`Successfully indexed ${item.name}`);
                    }
                }

                // Write the search index to disk
                const { files, errors: writeErrors } = await index.writeFiles({
                    outputPath: path.resolve("dist/pagefind"), // Output path
                });

                if (writeErrors.length > 0) {
                    console.error("Errors occurred while writing index files:", writeErrors);
                } else {
                    console.log("Search index files written successfully.");
                }
            },
        },
    };
}
paulrudy commented 1 month ago

@ColeTownsend would you mind sharing a little context for how to use this snippet of code?

shishkin commented 1 month ago

@paulrudy The example that @ColeTownsend provided is a reimplementation of this integration using Pagefind's Node API instead of CLI invocations. FYI, since 1.6.0 this integration has also switched to using Pagefind's Node API. For the context of this issue, feel free to use this integration's source to implement your own SSR pagefind integration.

ColeTownsend commented 1 month ago

@paulrudy ah sorry, this would be defined as a function (i was lazy and did it within my astro.config.mjs file) and then the function passed to your astro config.

//... rest of config file
integrations: [
  mdx(),
  react(),
  metaTags(),
  tailwind({
    applyBaseStyles: false,
  }),
  pagefindIntegration(),
],
paulrudy commented 1 month ago

@shishkin @ColeTownsend thank you both very much. Since astro-pagefind uses the Pagefind's Node API, I went with just using that. Works great!

(Switched from Astro server mode to hybrid so I could make use of this. Fortunately, I think I had only been using server mode because way back when, static pages in Astro didn't generate an actual 404 Response when serving a 404 page.)