Relative images were resolved against the page URL, but only the pathname was kept, so with a baseUrl on another domain the image still loaded from the search site. Keep the origin when the page URL has one, in the Component UI's resolveUrl filter and in both Default UI result templates. result_with_subs.svelte didn't resolve images at all before. Fixes #573
6.0 KiB
title, nav_title, nav_section, weight
| title | nav_title | nav_section | weight |
|---|---|---|---|
| <pagefind-results> | <pagefind-results> | Components | 20 |
Displays search results with automatic lazy loading. Results load their full data only when scrolled into view.
<pagefind-results></pagefind-results>
Attributes
| Attribute | Type | Default | Description |
|---|---|---|---|
show-images |
boolean | false |
Show/hide result images |
hide-sub-results |
boolean | false |
Hide anchor-based sub-results |
max-sub-results |
number | 3 |
Maximum number of sub-results per result |
max-results |
number | unlimited | Limit number of results shown |
link-target |
string | — | Set target attribute on result links (e.g., _blank for new tab) |
instance |
string | "default" |
Connect to a specific Pagefind instance |
Keyboard Navigation
When results are focused, use these keys to navigate:
| Key | Action |
|---|---|
↓ / ↑ |
Navigate between results |
Enter |
Follow the selected link |
Backspace |
Focus input and delete last character |
/ |
Focus the search input |
| Any letter | Focus input and type the character |
Custom Templates
Customize result rendering using <script type="text/pagefind-template"> elements inside the component. Templates use a simple syntax with variables, conditionals, and loops.
Basic Template
<pagefind-results>
<script type="text/pagefind-template">
<li class="my-result">
<h3>{{ meta.title }}</h3>
<a href="{{ url | safeUrl }}">{{ url }}</a>
<p>{{+ excerpt +}}</p>
</li>
</script>
</pagefind-results>
Your template must have a single root element (e.g. a single <li>). Keyboard navigation moves between <a> elements in the results list, so ensure your main result link is an <a> tag.
The full templating syntax can be seen in the adequate-little-templates package.
Available Data
Templates receive this data structure:
| Field | Description |
|---|---|
meta.title |
Page title |
meta.url |
Page URL |
meta.image |
Page image (if set) |
meta.image_alt |
Image alt text |
meta.* |
Any custom metadata |
excerpt |
Search excerpt with <mark> highlighting (use {{+ excerpt +}}) |
url |
Fallback URL |
sub_results |
Array of matching sections within the page |
options.* |
The attributes supplied to the <pagefind-results> element |
Each sub-result has: title, url, excerpt.
Template Filters
The template engine provides built-in filters. The Component UI registers the following additional filters:
resolveUrl(pageUrl)
Resolves a relative URL against a page URL. Absolute URLs are returned unchanged. If the page URL includes a domain, for example from a baseUrl on a merged index, the resolved URL keeps that domain.
"images/hero.png" | resolveUrl("/blog/post/") → /blog/post/images/hero.png
"images/hero.png" | resolveUrl("https://example.com/blog/post/") → https://example.com/blog/post/images/hero.png
Placeholder Template
While results are loading, a skeleton placeholder is shown. You can customize it with a second template using data-template="placeholder", as shown in the full example below. The placeholder template receives no data — it is static HTML.
Full Template Example
Here's the built-in template. Copy and customize it:
<pagefind-results>
<script type="text/pagefind-template">
<li class="pf-result">
<div class="pf-result-card">
{{#if and(options.show_images, meta.image)}}
<img class="pf-result-image" src="{{ meta.image | resolveUrl(meta.url | default(url)) }}" alt="{{ meta.image_alt | default(meta.title) }}">
{{/if}}
<div class="pf-result-content">
<p class="pf-result-title">
<a class="pf-result-link" href="{{ meta.url | default(url) | safeUrl }}"{{#if options.link_target}} target="{{ options.link_target }}"{{/if}}{{#if eq(options.link_target, "_blank")}} rel="noopener"{{/if}}>{{ meta.title }}</a>
</p>
{{#if excerpt}}
<p class="pf-result-excerpt">{{+ excerpt +}}</p>
{{/if}}
</div>
</div>
{{#if sub_results}}
<ul class="pf-heading-chips">
{{#each sub_results as sub}}
<li class="pf-heading-chip">
<a class="pf-heading-link" href="{{ sub.url | safeUrl }}"{{#if options.link_target}} target="{{ options.link_target }}"{{/if}}{{#if eq(options.link_target, "_blank")}} rel="noopener"{{/if}}>{{ sub.title }}</a>
<p class="pf-heading-excerpt">{{+ sub.excerpt +}}</p>
</li>
{{/each}}
</ul>
{{/if}}
</li>
</script>
<script type="text/pagefind-template" data-template="placeholder">
<li class="pf-result" aria-hidden="true">
<div class="pf-result-card">
<div class="pf-skeleton pf-skeleton-image"></div>
<div class="pf-result-content">
<p class="pf-result-title pf-skeleton pf-skeleton-title"></p>
<p class="pf-result-excerpt pf-skeleton pf-skeleton-excerpt"></p>
</div>
</div>
</li>
</script>
</pagefind-results>
Results Layout
By default, results display in a single column. You can change the layout of the results container using CSS variables, for example a grid layout:
:root {
--pf-results-display: grid;
--pf-results-columns: repeat(auto-fill, minmax(250px, 1fr));
--pf-results-gap: 16px;
}
See CSS Variables for all available layout variables.