rspress-plugin-typesense 0.0.2 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +253 -6
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -2,21 +2,268 @@
|
|
|
2
2
|
|
|
3
3
|
A plugin that brings lightning-fast, typo-tolerant search powered by Typesense to your Rspress site.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## About Typesense & Rspress
|
|
6
|
+
|
|
7
|
+
[**Typesense**](https://typesense.org/) is an open-source, lightning-fast search engine that delivers instant, typo-tolerant results with minimal setup. It's an open source alternative to Algolia and an easier-to-use alternative to ElasticSearch.
|
|
6
8
|
|
|
7
|
-
|
|
9
|
+
[**Rspress**](https://rspress.rs/) is a high-performance static site generator for documentation websites. Built with Rust, it offers a modern development experience and produces blazing-fast static sites.
|
|
10
|
+
|
|
11
|
+
Together, **Typesense** and **Rspress** provide a seamless way to add powerful, blazingly-fast search to modern documentation websites.
|
|
12
|
+
|
|
13
|
+
## Installation
|
|
8
14
|
|
|
9
15
|
```bash
|
|
10
16
|
npm install rspress-plugin-typesense
|
|
11
17
|
```
|
|
12
18
|
|
|
13
|
-
##
|
|
19
|
+
## Usage
|
|
14
20
|
|
|
15
|
-
|
|
21
|
+
### 1. Start typesense server
|
|
16
22
|
|
|
17
|
-
[
|
|
23
|
+
You can either self-host the Typesense server or use [Typesense Cloud service](https://cloud.typesense.org/). Follow this [getting started guide](https://typesense.org/docs/guide/install-typesense.html) to set up your server and obtain the API key and server URL.
|
|
18
24
|
|
|
19
|
-
|
|
25
|
+
### 2. Configure the plugin
|
|
26
|
+
|
|
27
|
+
First, add the plugin to your `rspress.config.ts`. You must provide your Typesense server details and an API key with **write permissions** so the plugin can create collections and index your documents during the build.
|
|
28
|
+
|
|
29
|
+
```ts
|
|
30
|
+
// rspress.config.ts
|
|
31
|
+
import { defineConfig } from '@rspress/core';
|
|
32
|
+
import { pluginTypesense } from 'rspress-plugin-typesense';
|
|
33
|
+
|
|
34
|
+
export default defineConfig({
|
|
35
|
+
plugins: [
|
|
36
|
+
pluginTypesense({
|
|
37
|
+
collectionName: 'my_docs',
|
|
38
|
+
serverConfig: {
|
|
39
|
+
nodes: [{ url: 'YOUR_TYPESENSE_SERVER_URL' }],
|
|
40
|
+
apiKey: 'YOUR_TYPESENSE_ADMIN_API_KEY', // Requires Write permissions
|
|
41
|
+
},
|
|
42
|
+
}),
|
|
43
|
+
],
|
|
44
|
+
});
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### 3. Override the search component
|
|
48
|
+
|
|
49
|
+
Next, override Rspress's default `Search` component via a [Custom Theme](https://rspress.rs/guide/basic/custom-theme).
|
|
50
|
+
|
|
51
|
+
Provide a **Search-Only API Key** here. For security reasons, **never expose your Admin API Key in the frontend**.
|
|
52
|
+
|
|
53
|
+
```tsx
|
|
54
|
+
// theme/index.tsx
|
|
55
|
+
import { Search as PluginTypesenseSearch } from 'rspress-plugin-typesense/runtime';
|
|
56
|
+
|
|
57
|
+
const Search = () => {
|
|
58
|
+
return (
|
|
59
|
+
<PluginTypesenseSearch
|
|
60
|
+
docSearchProps={{
|
|
61
|
+
typesenseServerConfig: {
|
|
62
|
+
nodes: [{ url: 'YOUR_TYPESENSE_SERVER_URL' }],
|
|
63
|
+
apiKey: 'YOUR_TYPESENSE_SEARCH_ONLY_API_KEY', // Safe for browsers
|
|
64
|
+
},
|
|
65
|
+
}}
|
|
66
|
+
/>
|
|
67
|
+
);
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
export { Search };
|
|
71
|
+
export * from '@rspress/core/theme-original';
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### 4. Build and index
|
|
75
|
+
|
|
76
|
+
Run the build command to generate your site and index your content into Typesense.
|
|
77
|
+
|
|
78
|
+
<PackageManagerTabs command="run build" />
|
|
79
|
+
|
|
80
|
+
All set! You've successfully integrated typo-tolerant search into your documentation. The plugin automatically handles filtering based on the user's current language and version.
|
|
81
|
+
|
|
82
|
+
## Plugin configuration (Backend)
|
|
83
|
+
|
|
84
|
+
The `pluginTypesense` function accepts an options object with the following properties:
|
|
85
|
+
|
|
86
|
+
```ts
|
|
87
|
+
export interface TypesensePluginOptions {
|
|
88
|
+
/**
|
|
89
|
+
* Typesense server connection options.
|
|
90
|
+
* The API key must have write permissions to create and index collections.
|
|
91
|
+
*/
|
|
92
|
+
serverConfig: ConfigurationOptions;
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* The base name of the Typesense collection.
|
|
96
|
+
* Note: The plugin creates dedicated localized collections (e.g., `my_docs_en`).
|
|
97
|
+
*/
|
|
98
|
+
collectionName: string;
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Optional schema overrides. Can be a global settings object or a map keyed by language.
|
|
102
|
+
*/
|
|
103
|
+
customCollectionSettings?: CustomCollectionSettingsConfig;
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Whether to index code blocks into Typesense.
|
|
107
|
+
* Defaults to `false` to avoid search noise and bloated index sizes.
|
|
108
|
+
*/
|
|
109
|
+
indexCodeBlocks?: boolean;
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Whether a failed indexing attempt should crash the build process.
|
|
113
|
+
* Defaults to `true`.
|
|
114
|
+
*/
|
|
115
|
+
failOnIndexError?: boolean;
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Whether to automatically filter search results by the active documentation version.
|
|
119
|
+
* Defaults to `true`.
|
|
120
|
+
*/
|
|
121
|
+
versionedSearch?: boolean;
|
|
122
|
+
}
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### customCollectionSettings
|
|
126
|
+
|
|
127
|
+
- **Type**:
|
|
128
|
+
|
|
129
|
+
```ts
|
|
130
|
+
type CustomCollectionSettingsConfig =
|
|
131
|
+
| CustomCollectionSettings
|
|
132
|
+
| Record<string, CustomCollectionSettings>;
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
- **Default**: `undefined`
|
|
136
|
+
|
|
137
|
+
Allows you to override the Typesense schema configuration. You can pass a single global configuration, or a map of configurations keyed by language (useful if you need specific token separators for languages like Chinese or Japanese).
|
|
138
|
+
|
|
139
|
+
#### Customizing schema and injecting custom data
|
|
140
|
+
|
|
141
|
+
For advanced use cases like adding custom tags for faceted search or boosting the search ranking of specific pages, you can extend the default schema and mutate records before they are indexed.
|
|
142
|
+
|
|
143
|
+
To do this:
|
|
144
|
+
|
|
145
|
+
1. Use the `getDefaultCollectionFields` helper in `customCollectionSettings` to safely append new fields to the collection schema.
|
|
146
|
+
2. Use the `transformRecord` hook to populate those fields or modify existing weights based on the `route`.
|
|
147
|
+
|
|
148
|
+
Here is an example showing how to add a custom `category` field for filtering, and how to boost the `page_rank` of "Getting Started" guides:
|
|
149
|
+
|
|
150
|
+
```ts
|
|
151
|
+
import {
|
|
152
|
+
pluginTypesense,
|
|
153
|
+
getDefaultCollectionFields,
|
|
154
|
+
} from 'rspress-plugin-typesense';
|
|
155
|
+
|
|
156
|
+
pluginTypesense({
|
|
157
|
+
collectionName: 'my_docs',
|
|
158
|
+
serverConfig: {
|
|
159
|
+
/* ... */
|
|
160
|
+
},
|
|
161
|
+
|
|
162
|
+
// 1. Extend the schema to add a custom 'category' field
|
|
163
|
+
customCollectionSettings: {
|
|
164
|
+
en: {
|
|
165
|
+
fields: (params) => [
|
|
166
|
+
...getDefaultCollectionFields(params),
|
|
167
|
+
{ name: 'category', type: 'string', facet: true, optional: true },
|
|
168
|
+
],
|
|
169
|
+
},
|
|
170
|
+
},
|
|
171
|
+
|
|
172
|
+
// 2. Mutate the record before it gets indexed
|
|
173
|
+
transformRecord(record, route) {
|
|
174
|
+
// Example: Inject a custom tag for faceted search
|
|
175
|
+
if (route.routePath.startsWith('/api/')) {
|
|
176
|
+
record.category = 'API Reference';
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// Example: Boost the search priority of important pages
|
|
180
|
+
if (route.routePath.includes('getting-started')) {
|
|
181
|
+
record.weight.page_rank = 100; // Default is 0
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
return record;
|
|
185
|
+
},
|
|
186
|
+
});
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
In the frontend, you could now pass `typesenseSearchParams: { filter_by: 'category:=API Reference' }` to your `<Search />` component to restrict results.
|
|
190
|
+
|
|
191
|
+
### indexCodeBlocks
|
|
192
|
+
|
|
193
|
+
- **Type**: `boolean`
|
|
194
|
+
- **Default**: `false`
|
|
195
|
+
|
|
196
|
+
By default, the plugin only indexes headers (`h1-h6`), paragraphs, lists and tables. Enabling this will also extract text from inside code blocks.
|
|
197
|
+
|
|
198
|
+
### failOnIndexError
|
|
199
|
+
|
|
200
|
+
- **Type**: `boolean`
|
|
201
|
+
- **Default**: `true`
|
|
202
|
+
|
|
203
|
+
By default, if the Typesense indexing step fails (e.g., network timeout), the build process will crash. Set this to `false` if you want your CI/CD deployments to succeed even if search indexing fails.
|
|
204
|
+
|
|
205
|
+
### versionedSearch
|
|
206
|
+
|
|
207
|
+
- **Type**: `boolean`
|
|
208
|
+
- **Default**: `true`
|
|
209
|
+
|
|
210
|
+
If your Rspress site utilizes multiple versions, the plugin tags every indexed document with its respective version and exposes this setting to the frontend via a virtual module. This ensures users only see search results relevant to the documentation version they are currently viewing. Set this to `false` if you want to search across all versions.
|
|
211
|
+
|
|
212
|
+
## Search component props (Frontend)
|
|
213
|
+
|
|
214
|
+
The `<PluginTypesenseSearch />` component accepts the following properties:
|
|
215
|
+
|
|
216
|
+
```ts
|
|
217
|
+
type SearchProps = {
|
|
218
|
+
docSearchProps: TypesenseDocSearchProps;
|
|
219
|
+
locales?: Locales;
|
|
220
|
+
};
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
### `docSearchProps`
|
|
224
|
+
|
|
225
|
+
- **Type**: `TypesenseDocSearchProps`
|
|
226
|
+
- **Required**: Yes (`typesenseServerConfig` must be provided)
|
|
227
|
+
|
|
228
|
+
Parameters passed directly to the underlying `typesense-docsearch-react` modal.
|
|
229
|
+
|
|
230
|
+
_You do not need to provide `typesenseCollectionName`. The plugin automatically injects the collection name via a virtual module._
|
|
231
|
+
|
|
232
|
+
### `locales`
|
|
233
|
+
|
|
234
|
+
- **Type**:
|
|
235
|
+
|
|
236
|
+
```ts
|
|
237
|
+
type Locales = Record<
|
|
238
|
+
string,
|
|
239
|
+
{ translations: DocSearchProps['translations']; placeholder: string }
|
|
240
|
+
>;
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
- **Default**: `{}`
|
|
244
|
+
|
|
245
|
+
Allows you to customize the placeholder and modal translations based on the active language. You can see the list of translations provided by the plugin [here](/src/runtime/locales.ts).
|
|
246
|
+
|
|
247
|
+
**Example:**
|
|
248
|
+
|
|
249
|
+
```tsx
|
|
250
|
+
import { Search as PluginTypesenseSearch } from 'rspress-plugin-typesense/runtime';
|
|
251
|
+
|
|
252
|
+
<PluginTypesenseSearch
|
|
253
|
+
locales={{
|
|
254
|
+
en: {
|
|
255
|
+
placeholder: 'Search documentation',
|
|
256
|
+
translations: {
|
|
257
|
+
button: {
|
|
258
|
+
buttonText: 'Search',
|
|
259
|
+
buttonAriaLabel: 'Search',
|
|
260
|
+
},
|
|
261
|
+
},
|
|
262
|
+
},
|
|
263
|
+
...ZH_LOCALES,
|
|
264
|
+
}}
|
|
265
|
+
/>;
|
|
266
|
+
```
|
|
20
267
|
|
|
21
268
|
## License
|
|
22
269
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rspress-plugin-typesense",
|
|
3
3
|
"description": "A plugin that adds lightning-fast, typo-tolerant, Typesense-powered search to your Rspress site",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.3",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
7
7
|
".": {
|
|
@@ -32,6 +32,7 @@
|
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
34
|
"cheerio": "^1.2.0",
|
|
35
|
+
"typesense": "^3.0.6",
|
|
35
36
|
"typesense-docsearch-css": "^0.4.1",
|
|
36
37
|
"typesense-docsearch-react": "^3.4.1"
|
|
37
38
|
},
|