Skip to content
This repository was archived by the owner on Jul 30, 2025. It is now read-only.

Commit c1dfd37

Browse files
haririaAndrew Hariri
andauthored
[nextra] Preload Search component (#903)
Co-authored-by: Andrew Hariri <hariria@usc.edu>
1 parent 7730a44 commit c1dfd37

File tree

7 files changed

+636
-475
lines changed

7 files changed

+636
-475
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import dynamic from "next/dynamic";
2+
3+
export const DynamicPreloadSearch = dynamic(() => import("./PreloadSearch"), {
4+
ssr: false,
5+
});
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
"use client";
2+
3+
import { useEffect } from "react";
4+
5+
export interface PreloadSearchProps {}
6+
7+
/**
8+
* Hack to Preloads Search by making a search request, then clearing it.
9+
*
10+
* NOTE: This must be client-side only as it includes a useEffect hook.
11+
*
12+
* @see https://github.com/shuding/nextra/blob/v3/packages/nextra-theme-docs/src/components/flexsearch.tsx
13+
* @see https://github.com/shuding/nextra/blob/v3/packages/nextra-theme-docs/src/components/search.tsx
14+
*/
15+
export function PreloadSearch(): JSX.Element | null {
16+
useEffect(() => {
17+
// Try desktop nav container first
18+
let container = document.querySelector(".nextra-nav-container");
19+
20+
// Fallback to mobile sidebar container
21+
if (!container) {
22+
container = document.querySelector(".nextra-sidebar-container");
23+
}
24+
25+
if (!container) return;
26+
27+
const input = container.querySelector(
28+
'input[type="search"]',
29+
) as HTMLInputElement;
30+
if (!input) return;
31+
32+
const nativeInputValueSetter = Object.getOwnPropertyDescriptor(
33+
window.HTMLInputElement.prototype,
34+
"value",
35+
)?.set;
36+
37+
nativeInputValueSetter?.call(input, "warmup");
38+
input.dispatchEvent(new Event("input", { bubbles: true }));
39+
40+
setTimeout(() => {
41+
nativeInputValueSetter?.call(input, "");
42+
input.dispatchEvent(new Event("input", { bubbles: true }));
43+
}, 500);
44+
}, []);
45+
46+
return null;
47+
}
48+
49+
export default PreloadSearch;
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export * from "./PreloadSearch";
2+
export * from "./DynamicPreloadSearch";

apps/nextra/pages/_app.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { GoogleAnalytics } from "@next/third-parties/google";
22
import { docsConfig } from "@docs-config";
33
import "../styles.css";
4+
import { DynamicPreloadSearch } from "@components/preload-search";
45

56
export const config = {
67
runtime: "experimental-edge",
@@ -15,6 +16,7 @@ export default function App({ Component, pageProps }) {
1516
return (
1617
<>
1718
<GoogleAnalytics gaId={docsConfig.googleAnalyticsId} />
19+
<DynamicPreloadSearch />
1820
<Component {...pageProps} />
1921
</>
2022
);

apps/nextra/pages/_document.tsx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,13 @@ class MyDocument extends Document {
2121
`,
2222
}}
2323
/>
24+
<link
25+
rel="preload"
26+
href="/_next/static/chunks/nextra-data-en.json"
27+
as="fetch"
28+
type="application/json"
29+
crossOrigin="anonymous"
30+
/>
2431
</Head>
2532
<body>
2633
<SkipNavLink styled />

0 commit comments

Comments
 (0)