Zach’s ugly mug (his face) Zach Leatherman

<pagefind-search> Web Component

December 01, 2023

I’m a huge fan of Pagefind, the fully static search engine.

The super cool thing about Pagefind is that it does not require an application server—you can host it on GitHub pages (which I’ve done in the demo below)! I currently use Pagefind on this very web site and on 11ty.dev.

I wanted a way to control the asset loading of the component using <is-land> so I built a small web component wrapper called <pagefind-search>. Read more about <is-land> usage below.

Usage

<script type="module" src="pagefind-search.js"></script>

<pagefind-search>
	<!-- Fallback to DuckDuckGo search -->
	<form action="https://duckduckgo.com/" method="get" style="min-height: 3.2em;"><!-- min-height to reduce CLS -->
		<label>
			Search for:
			<input type="search" name="q" autocomplete="off" autofocus>
		</label>
		<!-- Put your searchable domain here -->
		<input type="hidden" name="sites" value="www.zachleat.com">
		<button type="submit">Search</button>
	</form>
</pagefind-search>

<is-land> Use Cases

I don’t think it makes sense to always wrap this one in <is-land> (I don’t on my dedicated search page) but I do think that it unlocks a wider variety of user-preference user controlled lazily loaded use cases.

For example, putting the component in a dialog would lazily load the 20 kB (compressed) JavaScript bundle only when the search dialog is opened by the user.

<dialog>
	<is-land on:visible>
		<pagefind-search></pagefind-search>
	</is-land>
</dialog>

You could do the same with <details> too.

You could put the <pagefind-search> instance at the bottom of your page and only load it when the user scrolls down.

Lots of possibilities here!

Dev Notes

This one has some interesting declarative/programmatic boundaries that needed to be managed.

I wanted to make it easy to alias Pagefind options as HTML attributes, so I went with the convention that any attribute that started with an _ would be passed to the Pagefind constructor:

<pagefind-search _show_images="false"></pagefind-search>

The above calls new PagefindUI({ showImages: false }). If more options are added to Pagefind later, they’ll work with this approach without me having to make future changes.

And then for more advanced usage, there is a full escape hatch to JS with manual initialization:

<pagefind-search manual id="my-search"></pagefind-search>

<!-- type="module" is important here -->
<script type="module">
let el = document.querySelector("#my-search");
await el.pagefind({ showImages: false });
// `el.pagefindUI` to access the PagefindUI instance.
</script>

I also added a little pagefind-autofocus attribute to autofocus to the form element after it has initialized. As the native autofocus can be applied to any HTML element (think contenteditable), I went with the safer pagefind- prefixed attribute name.

<pagefind-search pagefind-autofocus></pagefind-search>

< Newer
is-land Web Component
Older >
Live Editing an Eleventy Project in CloudCannon with Bookshop

Zach Leatherman IndieWeb Avatar for https://zachleat.com/is a builder for the web at IndieWeb Avatar for https://cloudcannon.com/CloudCannon. He is the creator and maintainer of IndieWeb Avatar for https://www.11ty.devEleventy (11ty), an award-winning open source site generator. At one point he became entirely too fixated on web fonts. He has given 77 talks in nine different countries at events like Beyond Tellerrand, Smashing Conference, Jamstack Conf, CSSConf, and The White House. Formerly part of Netlify, Filament Group, NEJS CONF, and NebraskaJS. Learn more about Zach »

8 Reposts

IndieWeb Avatar for https://chrismcleod.devLiam BigelowNicolas HoizeyJayBaldur BjarnasonHawk TicehurstBryce Wraydasplan

13 Likes

Josh “Yoshi” VickersonwesruvJayBaldur BjarnasonAdam StoddardRoma KomarovdasplanJames' Coffee BlogNicolas HoizeyMiriam (still)Hawk TicehurstRich HolmanBryce Wray
8 Comments
  1. Hawk Ticehurst

    Hawk Ticehurst

    @zachleat Woah TIL about Pagefind ????

  2. Zach Leatherman

    Zach Leatherman

    @hawkticehurst yeah!! It’s awesome! I forgot to plug maybe the most impressive use of pagefind that I have: https://www.zachleat.com/twitter/static search of 46,000 pages ???? zachleat’s Twitter Archive

  3. Hawk Ticehurst

    Hawk Ticehurst

    @zachleat Wildddddd. This is so cool! Like, *of course*.. why *wouldn’t* you index your statically built files to create a low bandwidth search engine for your websites??

  4. Zach Leatherman

    Zach Leatherman

    @hawkticehurst (as always I’m gonna cc the brainchild of pagefind @bglw)

  5. Nicolas Hoizey

    Nicolas Hoizey

    @zachleat “I currently use Pagefind on this very web site and on 11ty.dev.” -> also in your Tweetback! ????

  6. Zach Leatherman

    Zach Leatherman

    @nhoizey haha yes, I forgot to include that one ???? https://fediverse.zachleat.com/@zachleat/111505839545250260

  7. Christian Engel

    Christian Engel

    A web component wrapper for Pagefind, the fully static search engine. I definitely have to try this one out! ????

  8. Zach Leatherman :verify:

    Zach Leatherman :verify:

    @mstrkapowski great!

Shamelessly plug your related post

These are webmentions via the IndieWeb and webmention.io.

Sharing on social media?

This is what will show up when you share this post on Social Media:

How did you do this? I automated my Open Graph images. (Peer behind the curtain at the test page)