Skip to content

Pagefind

Keep your custom Pagefind result renderer. Hosted retrieval replaces the static index, so PDFs, Office files and scanned documents become searchable alongside your pages.

On this page

1Install

Terminal
# Needs @docslurp/sdk 0.2.0 or newer (0.1.x lacks these exports).
npm install @docslurp/sdk@^0.3.0

# Then import:
# import { createDocSlurpPagefind } from '@docslurp/sdk/search-adapters';
Terminal
# Same client as @docslurp/sdk/search-adapters, one subpath per search client.
npm install @docslurp/contrib-search-compat

# Then import:
# import { createDocSlurpPagefind } from '@docslurp/contrib-search-compat/pagefind';

2Swap the module

Replace the dynamic import of pagefind.js with the DocSlurp adapter. Everything after search() keeps working.

search.tsDiff
- const pagefind = await import('/pagefind/pagefind.js');
+ import { createDocSlurpPagefind } from '@docslurp/sdk/search-adapters';
+ const pagefind = createDocSlurpPagefind({
+   apiUrl: 'https://docslurp.io',
+   clientKey: PUBLIC_DOCSLURP_CLIENT_KEY,
+   workspaceId: 'product-docs',
+   resolveUrl: hit => publicUrls[hit.citation.documentId], // your real routes
+ });

  // Unchanged: search(term) and lazy results[].data()
  const search = await pagefind.search('installation');
  const first = await search.results[0]?.data();

3Map source URLs

Pagefind results link to pages; DocSlurp results cite documents. resolveUrl is required: map each citation.documentId to the real public page that published it, for example from a JSON map you write while ingesting. It must return an https:// or site-relative URL for every hit, or the search throws rather than guessing a link.

Usage

search.ts
import { createDocSlurpPagefind } from '@docslurp/sdk/search-adapters';

// Map DocSlurp document IDs to the public pages that published them.
const publicUrls: Record<string, string> = await fetch('/search-map.json').then(r => r.json());

const pagefind = createDocSlurpPagefind({
  apiUrl: 'https://docslurp.io',
  clientKey: import.meta.env.PUBLIC_DOCSLURP_CLIENT_KEY,
  workspaceId: 'product-docs',
  resolveUrl: hit => publicUrls[hit.citation.documentId],
});

const search = await pagefind.search('installation');
for (const result of search.results.slice(0, 5)) {
  const data = await result.data();
  render({ url: data.url, title: data.meta.title, excerpt: data.excerpt }); // excerpt is HTML-escaped
}
await result.data()
{
  "url": "/docs/install",
  "meta": { "title": "install-guide.pdf" },
  "excerpt": "Install the CLI with npm, then set DOCSLURP_API_KEY.",
  "plain_excerpt": "Install the CLI with npm, then set DOCSLURP_API_KEY.",
  "word_count": 42,
  "filters": {},
  "anchors": [],
  "sub_results": [],
  "citation": { "documentId": "8f1c…", "filename": "install-guide.pdf", "pageNumbers": [3], "chunkIndex": 12 }
}
Terminal
curl https://docslurp.io/compat/pagefind/product-docs/search \
  -H "Authorization: Bearer $DOCSLURP_SEARCH_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "term": "installation" }'

The HTTP endpoint returns the same JSON without lazy data() wrappers. Without your URL map, its url is only filled when a result already carries a public source URL.

Compatibility

Supported

  • search(term), results[].data(), filters() returning {}
  • url, meta.title, excerpt (HTML-escaped) and plain_excerpt
  • citation on every result for page-level source links
  • Up to 100 ranked passages per query

Watch for

  • Stock Pagefind UI and offline index loading are out of scope. Use the Astro component, the widget or your own renderer.
  • Non-empty filters or sort throw a compatibility error.
  • Excerpts have no synthetic <mark> highlights.

Hand off to an agent

Working in a real codebase? Copy a prompt that tells a coding agent exactly what to change for Pagefind: which entry point to use, the supported contract, and what to validate before shipping. It contains no keys or secrets.

Review agent instructions

Before switching traffic, run through the go-live checklist. Stuck? See troubleshooting.

Jump to