Skip to content
15 changes: 14 additions & 1 deletion .github/workflows/search-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ jobs:
test-search:
name: Test Search Functionality
runs-on: ubuntu-latest
timeout-minutes: 15

steps:
- name: Checkout code
Expand All @@ -33,7 +34,19 @@ jobs:
uses: ./.github/actions/setup-deps

- name: Install Playwright browsers
run: npx playwright install chromium --with-deps
timeout-minutes: 10
# `--with-deps` runs `sudo apt-get`, which fetched and unpacked fine but
# then hung deterministically in the configure phase β€” zero output for the
# full timeout on every attempt. The cause is apt blocking on an
# interactive frontend (needrestart/debconf) with no TTY to answer it, so
# the old per-attempt-timeout-plus-retry just repeated the same stall and
# then blew the step cap. Force the debconf frontend non-interactive in the
# debconf database so the sudo apt-get Playwright spawns reads it and never
# prompts. One attempt, generous cap β€” no retry, because the failure was
# deterministic, not transient.
run: |
echo 'debconf debconf/frontend select Noninteractive' | sudo debconf-set-selections
npx playwright install chromium --with-deps

- name: Run search tests
run: ${{ steps.setup.outputs.runner }} test
Expand Down
24 changes: 17 additions & 7 deletions src/components/search-docs/search.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,15 +52,25 @@ export function Search({ className }: { className?: string }) {
if (typeof window !== "undefined") {
let pagefindModule: any;
try {
// Using eval to import pagefind.js is a workaround since the script isn't available during the build process.
// This also improves performance by loading the script only when needed, reducing initial page load time.
// A direct import would require committing the file with the codebase, which would change frequently
// with every content update.

pagefindModule = await (window as any).eval(
`import("${pagefindPath}/pagefind.js")`
// pagefind.js is generated at build time and lives outside the bundle. The
// webpackIgnore/turbopackIgnore comments tell both bundlers to leave this dynamic
// import alone (the reason the old code resorted to `window.eval`), emitting it as a
// runtime import. Avoiding `eval` means no CSP 'unsafe-eval' is required, which is
// what was breaking search under Chromium's stricter enforcement.
const pagefindUrl = new URL(
`${pagefindPath}/pagefind.js`,
window.location.origin
).href;

pagefindModule = await import(
/* webpackIgnore: true */
/* turbopackIgnore: true */
pagefindUrl
);
} catch (importError) {
// Surface the real cause (CSP, MIME type, or 404) instead of swallowing it.
// biome-ignore lint/suspicious/noConsole: needed to diagnose load failures in prod
console.error("Pagefind failed to load:", importError);
setError(
"Unable to load search functionality. For more information, please check this README: https://github.com/tinacms/tina-docs?tab=readme-ov-file#search-functionality and refresh the page."
);
Expand Down
Loading