diff --git a/docs/content/docs/_index.md b/docs/content/docs/_index.md
index 027c0c46..274c81fc 100644
--- a/docs/content/docs/_index.md
+++ b/docs/content/docs/_index.md
@@ -53,19 +53,6 @@ We can see that a bunch of content was indexed, and Pagefind will be running a p
Loading this in your browser, you should see a search input on your page. Try searching for some content and you will see results appear from your site.
-## Highlighting
-
-To highlight the search terms on results page, add the following snippet on every page that has been indexed
-
-```html
-
-
-
```
-To see the options available to PagefindHighlight, see [Highlight Config](/docs/highlight-config).
+Ensure that the `highlightParam` configured here matches the `highlightParam` given to Pagefind when searching.
+
+To see all options available to PagefindHighlight, see [Highlight Config](/docs/highlight-config).
diff --git a/docs/content/docs/search-config.md b/docs/content/docs/search-config.md
index b1697222..7fb114e9 100644
--- a/docs/content/docs/search-config.md
+++ b/docs/content/docs/search-config.md
@@ -67,6 +67,18 @@ Overrides the bundle directory. In most cases this should be automatically detec
Set the maximum length for generated excerpts. Defaults to `30`.
+### Highlight query parameter
+
+```json
+{
+ "highlightParam": "highlight"
+}
+```
+
+If set, Pagefind will add the search term as a query parameter under the same name.
+
+If using the [Pagefind highlight script](/docs/highlighting/), make sure this is configured to match.
+
### Index weight
See [multisite search > weighting](/docs/multisite/#changing-the-weighting-of-individual-indexes)
diff --git a/docs/content/docs/ui.md b/docs/content/docs/ui.md
index 2ef280b7..a578e9fe 100644
--- a/docs/content/docs/ui.md
+++ b/docs/content/docs/ui.md
@@ -152,19 +152,6 @@ new PagefindUI({
The number of milliseconds to wait after a user stops typing before performing a search. Defaults to `300`. If you wish to disable this, set to `0`.
-### Highlight query param name
-
-{{< diffcode >}}
-```javascript
-new PagefindUI({
- element: "#search",
-+ highlightQueryParamName: 'highlight'
-});
-```
-{{< /diffcode >}}
-
-If the parameter is changed here, it *must* be changed in the [`PagefindHighlight` object](/docs/highlight-config/#pagefindQueryParamName) as well.
-
### Translations
{{< diffcode >}}
diff --git a/pagefind/features/highlighting/highlighting_base.feature b/pagefind/features/highlighting/highlighting_results.feature
similarity index 98%
rename from pagefind/features/highlighting/highlighting_base.feature
rename to pagefind/features/highlighting/highlighting_results.feature
index 4ec035ed..fdd63ffb 100644
--- a/pagefind/features/highlighting/highlighting_base.feature
+++ b/pagefind/features/highlighting/highlighting_results.feature
@@ -1,4 +1,4 @@
-Feature: Highlighting Tests
+Feature: Highlighting Result Tests
Background:
Given I have the environment variables:
@@ -56,7 +56,7 @@ Feature: Highlighting Tests
- """
+ """
Given I have a "public/cat/index.html" file with the body:
"""
hello world
@@ -53,18 +53,18 @@ Feature: Base UI Tests
}
"""
Then There should be no logs
- Then The selector ".pagefind-ui__result-link[href$='?pagefind-highlight=hello&pagefind-highlight=world%21']" should contain "hello world"
+ Then The selector ".pagefind-ui__result-link[href$='?pagefind-highlight=hello&pagefind-highlight=world']" should contain "hello world"
- Scenario: Pagefind UI does not add highlight query params
+ Scenario: Pagefind UI does not add highlight query params by default
Given I have a "public/index.html" file with the body:
- """
+ """
- """
+ """
Given I have a "public/cat/index.html" file with the body:
"""
hello world
@@ -96,14 +96,14 @@ Feature: Base UI Tests
Scenario: Pagefind UI uses custom highlight query param name
Given I have a "public/index.html" file with the body:
- """
+ """
- """
+ """
Given I have a "public/cat/index.html" file with the body:
"""
hello world
@@ -132,12 +132,3 @@ Feature: Base UI Tests
"""
Then There should be no logs
Then The selector ".pagefind-ui__result-link[href$='?custom-param=hello&custom-param=world']" should contain "hello world"
- When I evaluate:
- """
- async function() {
- window.pui.triggerSearch("hello world!");
- await new Promise(r => setTimeout(r, 1500)); // TODO: await el in humane
- }
- """
- Then There should be no logs
- Then The selector ".pagefind-ui__result-link[href$='?custom-param=hello&custom-param=world%21']" should contain "hello world"
diff --git a/pagefind/features/ui/ui_hooks.feature b/pagefind/features/ui/ui_hooks.feature
index 3c645c4a..2dd637b9 100644
--- a/pagefind/features/ui/ui_hooks.feature
+++ b/pagefind/features/ui/ui_hooks.feature
@@ -13,8 +13,7 @@ Feature: UI Hooks
"""
diff --git a/pagefind_ui/default/svelte/ui.svelte b/pagefind_ui/default/svelte/ui.svelte
index c74cdb5e..1522b7fa 100644
--- a/pagefind_ui/default/svelte/ui.svelte
+++ b/pagefind_ui/default/svelte/ui.svelte
@@ -34,9 +34,6 @@
export let merge_index = [];
export let trigger_search_term = "";
export let translations = {};
- // this is the name of the query param which is used to highlight the search terms after the user has navigated to a result page
- // consider exposing the prop in the constructor in camelCase if needed
- export let highlight_query_param_name = "pagefind-highlight";
let val = "";
$: if (trigger_search_term) {
@@ -44,16 +41,6 @@
trigger_search_term = "";
}
- // this could be changed to not split if the value is quoted
- // ex: val = `hello world "foo bar"` highlightWords = ["hello", "world", "foo bar"]
-
- $: highlightWords = val.split(" ");
-
- $: highlight_query_param = new URLSearchParams(
- highlightWords.map((word) => {
- return [highlight_query_param_name, word];
- })
- ).toString();
let pagefind;
let input_el,
clear_el,
@@ -318,23 +305,9 @@
{#each searchResult.results.slice(0, show) as result (result.id)}
{#if show_sub_results}
-
+
{:else}
-
+
{/if}
{/each}
diff --git a/pagefind_ui/default/ui-core.js b/pagefind_ui/default/ui-core.js
index cd2fcdea..07e6a2b2 100644
--- a/pagefind_ui/default/ui-core.js
+++ b/pagefind_ui/default/ui-core.js
@@ -26,11 +26,6 @@ export class PagefindUI {
let debounceTimeoutMs = opts.debounceTimeoutMs ?? 300;
let mergeIndex = opts.mergeIndex ?? [];
let translations = opts.translations ?? [];
- // setting the param to null should disable highlighting, hence this more complicated check
- let highlightQueryParamName = "pagefind-highlight";
- if (opts.highlightQueryParamName !== undefined) {
- highlightQueryParamName = opts.highlightQueryParamName;
- }
// Remove the UI-specific config before passing it along to the Pagefind backend
delete opts["element"];
@@ -67,7 +62,6 @@ export class PagefindUI {
debounce_timeout_ms: debounceTimeoutMs,
merge_index: mergeIndex,
translations,
- highlight_query_param_name: highlightQueryParamName,
pagefind_options: opts,
},
});
diff --git a/pagefind_web_js/lib/coupled_search.ts b/pagefind_web_js/lib/coupled_search.ts
index 0e9567f5..d340971b 100644
--- a/pagefind_web_js/lib/coupled_search.ts
+++ b/pagefind_web_js/lib/coupled_search.ts
@@ -22,6 +22,7 @@ class PagefindInstance {
indexWeight: number;
excerptLength: number;
mergeFilter: Object;
+ highlightParam: string | null;
loaded_chunks: Record>;
loaded_filters: Record>;
@@ -60,6 +61,7 @@ class PagefindInstance {
this.indexWeight = opts.indexWeight ?? 1;
this.excerptLength = opts.excerptLength ?? 30;
this.mergeFilter = opts.mergeFilter ?? {};
+ this.highlightParam = opts.highlightParam ?? null;
this.loaded_chunks = {};
this.loaded_filters = {};
@@ -88,7 +90,7 @@ class PagefindInstance {
}
async options(options: PagefindIndexOptions) {
- const opts = ["basePath", "baseUrl", "indexWeight", "excerptLength", "mergeFilter"];
+ const opts = ["basePath", "baseUrl", "indexWeight", "excerptLength", "mergeFilter", "highlightParam"];
for (const [k, v] of Object.entries(options)) {
if (k === "mergeFilter") {
let filters = this.stringifyFilters(v);
@@ -100,6 +102,7 @@ class PagefindInstance {
if (k === "indexWeight" && typeof v === "number") this.indexWeight = v;
if (k === "excerptLength" && typeof v === "number") this.excerptLength = v;
if (k === "mergeFilter" && typeof v === "object") this.mergeFilter = v;
+ if (k === "highlightParam" && typeof v === "string") this.highlightParam = v;
} else {
console.warn(`Unknown Pagefind option ${k}. Allowed options: [${opts.join(', ')}]`);
}
@@ -245,7 +248,7 @@ class PagefindInstance {
return JSON.parse(new TextDecoder().decode(fragment));
}
- async loadFragment(hash: string, weighted_locations: PagefindWordLocation[] = []) {
+ async loadFragment(hash: string, weighted_locations: PagefindWordLocation[] = [], search_term: string) {
if (!this.loaded_fragments[hash]) {
this.loaded_fragments[hash] = this._loadFragment(hash);
}
@@ -262,8 +265,8 @@ class PagefindInstance {
}
if (!fragment.raw_url) {
fragment.raw_url = fragment.url;
- fragment.url = this.fullUrl(fragment.raw_url);
}
+ fragment.url = this.processedUrl(fragment.raw_url, search_term);
const excerpt_start = calculate_excerpt_region(weighted_locations, this.excerptLength);
fragment.excerpt = build_excerpt(fragment.raw_content, excerpt_start, this.excerptLength, fragment.locations);
@@ -281,6 +284,32 @@ class PagefindInstance {
return `${this.baseUrl}/${raw}`.replace(/\/+/g, "/").replace(/^(https?:\/)/, "$1/");
}
+ processedUrl(url: string, search_term: string) {
+ const normalized = this.fullUrl(url);
+ if (this.highlightParam === null) {
+ return normalized;
+ }
+ let individual_terms = search_term.split(/\s+/);
+ try {
+ // This will error is it is not a FQDN
+ let processed = new URL(normalized);
+ for (const term of individual_terms) {
+ processed.searchParams.append(this.highlightParam, term);
+ }
+ return processed.toString();
+ } catch(e) {
+ try {
+ let processed = new URL(`https://example.com${normalized}`);
+ for (const term of individual_terms) {
+ processed.searchParams.append(this.highlightParam, term);
+ }
+ return processed.toString().replace(/^https:\/\/example\.com/, "");
+ } catch (e) {
+ return normalized;
+ }
+ }
+ }
+
async getPtr() {
while (this.raw_ptr === null) {
await asyncSleep(50);
@@ -438,7 +467,7 @@ class PagefindInstance {
id: hash,
score: parseFloat(score) * this.indexWeight,
words: locations,
- data: async () => await this.loadFragment(hash, weighted_locations)
+ data: async () => await this.loadFragment(hash, weighted_locations, term)
}
});
diff --git a/pagefind_web_js/lib/highlight.ts b/pagefind_web_js/lib/highlight.ts
index 7feeabd5..aa0ff12a 100644
--- a/pagefind_web_js/lib/highlight.ts
+++ b/pagefind_web_js/lib/highlight.ts
@@ -12,13 +12,13 @@ import Mark from "mark.js";
type pagefindHighlightOptions = {
markContext?: string | HTMLElement | HTMLElement[] | NodeList | null;
- pagefindQueryParamName?: string;
+ highlightParam?: string;
markOptions?: Omit;
addStyles?: boolean;
};
export default class PagefindHighlight {
- pagefindQueryParamName: string;
+ highlightParam: string;
markContext: string | HTMLElement | HTMLElement[] | NodeList | null;
markOptions: Mark.MarkOptions;
addStyles: boolean;
@@ -26,7 +26,7 @@ export default class PagefindHighlight {
constructor(
options: pagefindHighlightOptions = {
markContext: null,
- pagefindQueryParamName: "pagefind-highlight",
+ highlightParam: "pagefind-highlight",
markOptions: {
className: "pagefind-highlight",
exclude: ["[data-pagefind-ignore]", "[data-pagefind-ignore] *"],
@@ -34,11 +34,11 @@ export default class PagefindHighlight {
addStyles: true,
}
) {
- const { pagefindQueryParamName, markContext, markOptions, addStyles } =
+ const { highlightParam, markContext, markOptions, addStyles } =
options;
- this.pagefindQueryParamName =
- pagefindQueryParamName ?? "pagefind-highlight";
+ this.highlightParam =
+ highlightParam ?? "pagefind-highlight";
this.addStyles = addStyles ?? true;
this.markContext = markContext !== undefined ? markContext : null;
this.markOptions =
@@ -92,7 +92,7 @@ export default class PagefindHighlight {
}
highlight() {
- const params = this.getHighlightParams(this.pagefindQueryParamName);
+ const params = this.getHighlightParams(this.highlightParam);
if (!params || params.length === 0) return;
this.addStyles &&
this.addHighlightStyles(this.markOptions.className as string);
diff --git a/pagefind_web_js/types/index.d.ts b/pagefind_web_js/types/index.d.ts
index 761d94e8..aad34393 100644
--- a/pagefind_web_js/types/index.d.ts
+++ b/pagefind_web_js/types/index.d.ts
@@ -21,6 +21,10 @@ declare global {
* Only applies in multisite setups.
*/
mergeFilter?: Object,
+ /**
+ * If set, will ass the search term as a query parameter under this key, for use with Pagefind's highlighting script.
+ */
+ highlightParam?: string,
language?: string,
/**
* Whether an instance of Pagefind is the primary index or not (for multisite).