mirror of
https://github.com/hanzo-docs/docs.git
synced 2026-10-25 04:20:02 +00:00
Core: Support Orama Cloud crawler index
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'fumadocs-core': patch
|
||||
---
|
||||
|
||||
Support Orama Cloud crawler index
|
||||
@@ -24,11 +24,7 @@ if (item === 'true') {
|
||||
}
|
||||
`;
|
||||
|
||||
export function Provider({
|
||||
children,
|
||||
}: {
|
||||
children: ReactNode;
|
||||
}): React.ReactElement {
|
||||
export function Provider({ children }: { children: ReactNode }) {
|
||||
return (
|
||||
<RootProvider
|
||||
search={{
|
||||
|
||||
@@ -3,11 +3,13 @@ title: Orama Cloud
|
||||
description: Integrate with Orama Cloud
|
||||
---
|
||||
|
||||
## Setup
|
||||
|
||||
To begin, create an account on Orama Cloud.
|
||||
|
||||
1. Create a new index from Dashboard.
|
||||
## REST API
|
||||
|
||||
REST API integration requires your docs to upload the indexes.
|
||||
|
||||
1. Create a new REST API index from Dashboard.
|
||||
2. Use the following schema:
|
||||
|
||||
```json
|
||||
@@ -23,7 +25,7 @@ To begin, create an account on Orama Cloud.
|
||||
}
|
||||
```
|
||||
|
||||
3. Then, using the API key and index ID from dashboard, create a script to sync search indexes.
|
||||
3. Then, using the private API key and index ID from dashboard, create a script to sync search indexes.
|
||||
|
||||
```json doc-gen:file
|
||||
{
|
||||
@@ -68,3 +70,50 @@ const { search, setSearch, query } = useDocsSearch({
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
## Web Crawler
|
||||
|
||||
1. Create a Crawler index from dashboard, and configure it correctly with the "Documentation" preset.
|
||||
2. Copy the public API key and index ID from dashboard
|
||||
|
||||
### Search Client
|
||||
|
||||
Same as REST API integration, but make sure to set `index` to `crawler`.
|
||||
|
||||
```ts
|
||||
import { useDocsSearch } from 'fumadocs-core/search/client';
|
||||
import { OramaClient } from '@oramacloud/client';
|
||||
|
||||
const client = new OramaClient({
|
||||
endpoint: '<endpoint_url>',
|
||||
api_key: '<api_key>',
|
||||
});
|
||||
|
||||
const { search, setSearch, query } = useDocsSearch({
|
||||
type: 'orama-cloud',
|
||||
index: 'crawler',
|
||||
client,
|
||||
params: {
|
||||
// optional search params
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
It's same for Fumadocs UI:
|
||||
|
||||
```tsx
|
||||
'use client';
|
||||
|
||||
import { OramaClient } from '@oramacloud/client';
|
||||
import type { SharedProps } from 'fumadocs-ui/components/dialog/search';
|
||||
import SearchDialog from 'fumadocs-ui/components/dialog/search-orama';
|
||||
|
||||
const client = new OramaClient({
|
||||
endpoint: '<endpoint_url>',
|
||||
api_key: '<api_key>',
|
||||
});
|
||||
|
||||
export default function CustomSearchDialog(props: SharedProps) {
|
||||
return <SearchDialog {...props} index="crawler" client={client} />;
|
||||
}
|
||||
```
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
"@radix-ui/react-popover": "^1.1.6",
|
||||
"@radix-ui/react-slot": "^1.1.2",
|
||||
"@radix-ui/react-tooltip": "^1.1.8",
|
||||
"@shikijs/rehype": "^3.1.0",
|
||||
"@shikijs/rehype": "^3.2.1",
|
||||
"@theguild/remark-mermaid": "^0.2.0",
|
||||
"class-variance-authority": "^0.7.1",
|
||||
"fumadocs-core": "workspace:*",
|
||||
@@ -33,9 +33,9 @@
|
||||
"hast-util-to-jsx-runtime": "^2.3.6",
|
||||
"katex": "^0.16.21",
|
||||
"lucide-react": "^0.479.0",
|
||||
"next": "15.2.1",
|
||||
"next": "15.2.2",
|
||||
"octokit": "^4.1.2",
|
||||
"oxc-transform": "^0.56.5",
|
||||
"oxc-transform": "^0.58.1",
|
||||
"phenomenon": "^1.6.0",
|
||||
"react": "^19.0.0",
|
||||
"react-dom": "^19.0.0",
|
||||
@@ -47,17 +47,17 @@
|
||||
"remark-rehype": "^11.1.1",
|
||||
"remark-stringify": "^11.0.0",
|
||||
"scroll-into-view-if-needed": "^3.1.0",
|
||||
"shiki": "^3.1.0",
|
||||
"shiki": "^3.2.1",
|
||||
"tailwind-merge": "^3.0.2",
|
||||
"twoslash": "^0.3.1",
|
||||
"zod": "^3.24.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@fumadocs/cli": "workspace:*",
|
||||
"@next/bundle-analyzer": "15.2.1",
|
||||
"@next/env": "15.2.1",
|
||||
"@next/eslint-plugin-next": "15.2.1",
|
||||
"@tailwindcss/postcss": "^4.0.12",
|
||||
"@next/bundle-analyzer": "15.2.2",
|
||||
"@next/env": "15.2.2",
|
||||
"@next/eslint-plugin-next": "15.2.2",
|
||||
"@tailwindcss/postcss": "^4.0.14",
|
||||
"@types/hast": "^3.0.4",
|
||||
"@types/mdx": "^2.0.13",
|
||||
"@types/node": "22.13.10",
|
||||
@@ -68,7 +68,7 @@
|
||||
"gray-matter": "^4.0.3",
|
||||
"next-validate-link": "^1.5.1",
|
||||
"postcss": "^8.5.3",
|
||||
"tailwindcss": "^4.0.12",
|
||||
"tailwindcss": "^4.0.14",
|
||||
"tailwindcss-animate": "^1.0.7",
|
||||
"ts-morph": "^25.0.1",
|
||||
"tsconfig": "workspace:*",
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
"@fumadocs/content-collections": "workspace:*",
|
||||
"fumadocs-core": "workspace:*",
|
||||
"fumadocs-ui": "workspace:*",
|
||||
"next": "^15.2.1",
|
||||
"next": "^15.2.2",
|
||||
"react": "19.0.0",
|
||||
"react-dom": "19.0.0"
|
||||
},
|
||||
|
||||
@@ -8,12 +8,12 @@
|
||||
"start": "next start"
|
||||
},
|
||||
"dependencies": {
|
||||
"@orama/stopwords": "^3.1.2",
|
||||
"@orama/tokenizers": "^3.1.2",
|
||||
"@orama/stopwords": "^3.1.3",
|
||||
"@orama/tokenizers": "^3.1.3",
|
||||
"fumadocs-core": "workspace:*",
|
||||
"fumadocs-mdx": "workspace:*",
|
||||
"fumadocs-ui": "workspace:*",
|
||||
"next": "15.2.1",
|
||||
"next": "15.2.2",
|
||||
"react": "19.0.0",
|
||||
"react-dom": "19.0.0"
|
||||
},
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
"fumadocs-core": "workspace:*",
|
||||
"fumadocs-mdx": "workspace:*",
|
||||
"fumadocs-ui": "workspace:*",
|
||||
"next": "15.2.1",
|
||||
"next": "15.2.2",
|
||||
"react": "19.0.0",
|
||||
"react-dom": "19.0.0"
|
||||
},
|
||||
|
||||
@@ -10,25 +10,25 @@
|
||||
"types:check": "fumadocs-mdx && tsc --noEmit"
|
||||
},
|
||||
"dependencies": {
|
||||
"@scalar/api-client-react": "^1.1.42",
|
||||
"@scalar/api-client-react": "^1.2.1",
|
||||
"fumadocs-core": "workspace:*",
|
||||
"fumadocs-mdx": "workspace:*",
|
||||
"fumadocs-openapi": "workspace:*",
|
||||
"fumadocs-ui": "workspace:*",
|
||||
"next": "15.2.1",
|
||||
"next": "15.2.2",
|
||||
"react": "19.0.0",
|
||||
"react-dom": "19.0.0",
|
||||
"shiki": "^3.1.0",
|
||||
"shiki": "^3.2.1",
|
||||
"zod": "^3.24.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tailwindcss/postcss": "^4.0.12",
|
||||
"@tailwindcss/postcss": "^4.0.14",
|
||||
"@types/mdx": "^2.0.13",
|
||||
"@types/react": "^19.0.10",
|
||||
"@types/react-dom": "^19.0.4",
|
||||
"postcss": "^8.5.3",
|
||||
"rimraf": "^6.0.1",
|
||||
"tailwindcss": "^4.0.12",
|
||||
"tailwindcss": "^4.0.14",
|
||||
"typescript": "^5.8.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
"fast-glob": "^3.3.3",
|
||||
"fumadocs-core": "workspace:*",
|
||||
"fumadocs-ui": "workspace:*",
|
||||
"next": "15.2.1",
|
||||
"next": "15.2.2",
|
||||
"react": "19.0.0",
|
||||
"react-dom": "19.0.0"
|
||||
},
|
||||
|
||||
+1
-1
@@ -23,7 +23,7 @@
|
||||
"concurrently": "^9.1.2",
|
||||
"eslint": "^9.20.1",
|
||||
"eslint-plugin-react": "^7.37.4",
|
||||
"eslint-plugin-react-hooks": "5.1.0",
|
||||
"eslint-plugin-react-hooks": "5.2.0",
|
||||
"eslint-plugin-tailwindcss": "^3.18.0",
|
||||
"prettier": "^3.5.3",
|
||||
"rimraf": "^6.0.1",
|
||||
|
||||
@@ -97,19 +97,19 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@formatjs/intl-localematcher": "^0.6.0",
|
||||
"@orama/orama": "^3.1.2",
|
||||
"@shikijs/rehype": "^3.1.0",
|
||||
"@shikijs/transformers": "^3.1.0",
|
||||
"@orama/orama": "^3.1.3",
|
||||
"@shikijs/rehype": "^3.2.1",
|
||||
"@shikijs/transformers": "^3.2.1",
|
||||
"github-slugger": "^2.0.0",
|
||||
"hast-util-to-estree": "^3.1.3",
|
||||
"hast-util-to-jsx-runtime": "^2.3.6",
|
||||
"image-size": "^2.0.0",
|
||||
"image-size": "^2.0.1",
|
||||
"negotiator": "^1.0.0",
|
||||
"react-remove-scroll": "^2.6.3",
|
||||
"remark": "^15.0.0",
|
||||
"remark-gfm": "^4.0.1",
|
||||
"scroll-into-view-if-needed": "^3.1.0",
|
||||
"shiki": "^3.1.0",
|
||||
"shiki": "^3.2.1",
|
||||
"unist-util-visit": "^5.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
@@ -127,7 +127,7 @@
|
||||
"eslint-config-custom": "workspace:*",
|
||||
"mdast-util-mdx-jsx": "^3.2.0",
|
||||
"mdast-util-mdxjs-esm": "^2.0.1",
|
||||
"next": "^15.2.1",
|
||||
"next": "^15.2.2",
|
||||
"remark-mdx": "^3.1.0",
|
||||
"remark-rehype": "^11.1.1",
|
||||
"tsconfig": "workspace:*",
|
||||
|
||||
@@ -3,8 +3,22 @@ import type { OramaClient, ClientSearchParams } from '@oramacloud/client';
|
||||
import { removeUndefined } from '@/utils/remove-undefined';
|
||||
import type { OramaIndex } from '@/search/orama-cloud';
|
||||
|
||||
interface CrawlerIndex {
|
||||
path: string;
|
||||
title: string;
|
||||
content: string;
|
||||
section: string;
|
||||
category: string;
|
||||
}
|
||||
|
||||
export interface OramaCloudOptions {
|
||||
client: OramaClient;
|
||||
/**
|
||||
* The type of your index.
|
||||
*
|
||||
* You can set it to `crawler` if you use crawler instead of the JSON index with schema provided by Fumadocs
|
||||
*/
|
||||
index?: 'default' | 'crawler';
|
||||
params?: ClientSearchParams;
|
||||
}
|
||||
|
||||
@@ -13,7 +27,48 @@ export async function searchDocs(
|
||||
tag: string | undefined,
|
||||
options: OramaCloudOptions,
|
||||
): Promise<SortedResult[]> {
|
||||
const { client, params: extraParams = {} } = options;
|
||||
const list: SortedResult[] = [];
|
||||
const { index = 'default', client, params: extraParams = {} } = options;
|
||||
|
||||
if (index === 'crawler') {
|
||||
const result = await client.search({
|
||||
...extraParams,
|
||||
term: query,
|
||||
where: {
|
||||
category: tag
|
||||
? {
|
||||
eq: tag.slice(0, 1).toUpperCase() + tag.slice(1),
|
||||
}
|
||||
: undefined,
|
||||
...extraParams.where,
|
||||
},
|
||||
limit: 10,
|
||||
});
|
||||
if (!result) return list;
|
||||
|
||||
if (index === 'crawler') {
|
||||
for (const hit of result.hits) {
|
||||
const doc = hit.document as unknown as CrawlerIndex;
|
||||
|
||||
list.push(
|
||||
{
|
||||
id: hit.id,
|
||||
type: 'page',
|
||||
content: doc.title,
|
||||
url: doc.path,
|
||||
},
|
||||
{
|
||||
id: 'page' + hit.id,
|
||||
type: 'text',
|
||||
content: doc.content,
|
||||
url: doc.path,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
||||
const params: ClientSearchParams = {
|
||||
...extraParams,
|
||||
@@ -30,10 +85,9 @@ export async function searchDocs(
|
||||
};
|
||||
|
||||
const result = await client.search(params);
|
||||
if (!result) return [];
|
||||
if (!result || !result.groups) return list;
|
||||
|
||||
const list: SortedResult[] = [];
|
||||
for (const item of result.groups ?? []) {
|
||||
for (const item of result.groups) {
|
||||
let addedHead = false;
|
||||
|
||||
for (const hit of item.result) {
|
||||
|
||||
@@ -8,16 +8,16 @@
|
||||
"@content-collections/core": "^0.8.2",
|
||||
"@content-collections/mdx": "^0.2.2",
|
||||
"@content-collections/next": "^0.2.6",
|
||||
"@tailwindcss/postcss": "^4.0.12",
|
||||
"@tailwindcss/postcss": "^4.0.14",
|
||||
"@types/mdx": "^2.0.13",
|
||||
"@types/node": "22.13.10",
|
||||
"@types/react": "^19.0.10",
|
||||
"@types/react-dom": "^19.0.4",
|
||||
"next": "15.2.1",
|
||||
"next": "15.2.2",
|
||||
"postcss": "^8.5.3",
|
||||
"react": "^19.0.0",
|
||||
"react-dom": "^19.0.0",
|
||||
"tailwindcss": "^4.0.12",
|
||||
"tailwindcss": "^4.0.14",
|
||||
"typescript": "^5.8.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
"estree-util-to-js": "^2.0.0",
|
||||
"estree-util-value-to-estree": "^3.3.2",
|
||||
"npm-to-yarn": "^3.0.1",
|
||||
"oxc-transform": "^0.56.5",
|
||||
"oxc-transform": "^0.58.1",
|
||||
"unist-util-visit": "^5.0.0",
|
||||
"zod": "^3.24.2"
|
||||
},
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
"eslint-config-custom": "workspace:*",
|
||||
"fast-glob": "^3.3.3",
|
||||
"fumadocs-core": "workspace:*",
|
||||
"next": "15.2.1",
|
||||
"next": "15.2.2",
|
||||
"tsconfig": "workspace:*",
|
||||
"unified": "^11.0.5",
|
||||
"vfile": "^6.0.3"
|
||||
|
||||
@@ -69,7 +69,7 @@
|
||||
"eslint-config-custom": "workspace:*",
|
||||
"fumadocs-core": "workspace:*",
|
||||
"mdast-util-mdx-jsx": "^3.2.0",
|
||||
"next": "^15.2.1",
|
||||
"next": "^15.2.2",
|
||||
"tsconfig": "workspace:*",
|
||||
"unified": "^11.0.5",
|
||||
"vfile": "^6.0.3",
|
||||
|
||||
@@ -54,7 +54,7 @@
|
||||
"@radix-ui/react-dialog": "^1.1.6",
|
||||
"@radix-ui/react-select": "^2.1.6",
|
||||
"@radix-ui/react-slot": "^1.1.2",
|
||||
"@scalar/openapi-parser": "0.10.9",
|
||||
"@scalar/openapi-parser": "0.10.10",
|
||||
"ajv-draft-04": "^1.0.0",
|
||||
"class-variance-authority": "^0.7.1",
|
||||
"fast-glob": "^3.3.3",
|
||||
@@ -64,24 +64,24 @@
|
||||
"hast-util-to-jsx-runtime": "^2.3.6",
|
||||
"js-yaml": "^4.1.0",
|
||||
"lucide-react": "^0.479.0",
|
||||
"next-themes": "^0.4.4",
|
||||
"next-themes": "^0.4.6",
|
||||
"openapi-sampler": "^1.6.1",
|
||||
"react-hook-form": "^7.54.2",
|
||||
"remark": "^15.0.1",
|
||||
"remark-rehype": "^11.1.1",
|
||||
"shiki": "^3.1.0",
|
||||
"shiki": "^3.2.1",
|
||||
"xml-js": "^1.6.11"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@scalar/api-client-react": "^1.1.42",
|
||||
"@scalar/api-client-react": "^1.2.1",
|
||||
"@types/js-yaml": "^4.0.9",
|
||||
"@types/node": "22.13.10",
|
||||
"@types/openapi-sampler": "^1.0.3",
|
||||
"@types/react": "^19.0.10",
|
||||
"eslint-config-custom": "workspace:*",
|
||||
"next": "15.2.1",
|
||||
"next": "15.2.2",
|
||||
"openapi-types": "^12.1.3",
|
||||
"tailwindcss": "^4.0.12",
|
||||
"tailwindcss": "^4.0.14",
|
||||
"tsc-alias": "^1.8.11",
|
||||
"tsconfig": "workspace:*"
|
||||
},
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@radix-ui/react-popover": "^1.1.6",
|
||||
"@shikijs/twoslash": "^3.1.0",
|
||||
"@shikijs/twoslash": "^3.2.1",
|
||||
"mdast-util-from-markdown": "^2.0.2",
|
||||
"mdast-util-gfm": "^3.1.0",
|
||||
"mdast-util-to-hast": "^13.2.0",
|
||||
@@ -55,7 +55,7 @@
|
||||
"@types/react": "^19.0.10",
|
||||
"eslint-config-custom": "workspace:*",
|
||||
"fumadocs-ui": "workspace:*",
|
||||
"shiki": "^3.1.0",
|
||||
"shiki": "^3.2.1",
|
||||
"tsconfig": "workspace:*"
|
||||
},
|
||||
"peerDependencies": {
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
"hast-util-to-jsx-runtime": "^2.3.6",
|
||||
"remark": "^15.0.1",
|
||||
"remark-rehype": "^11.1.1",
|
||||
"shiki": "^3.1.0",
|
||||
"shiki": "^3.2.1",
|
||||
"ts-morph": "^25.0.1",
|
||||
"unist-util-visit": "^5.0.0"
|
||||
},
|
||||
|
||||
@@ -76,22 +76,22 @@
|
||||
"class-variance-authority": "^0.7.1",
|
||||
"lodash.merge": "^4.6.2",
|
||||
"lucide-react": "^0.479.0",
|
||||
"next-themes": "^0.4.4",
|
||||
"next-themes": "^0.4.6",
|
||||
"postcss-selector-parser": "^7.1.0",
|
||||
"react-medium-image-zoom": "^5.2.14",
|
||||
"tailwind-merge": "^3.0.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@fumadocs/cli": "workspace:*",
|
||||
"@next/eslint-plugin-next": "^15.2.1",
|
||||
"@tailwindcss/cli": "^4.0.12",
|
||||
"@next/eslint-plugin-next": "^15.2.2",
|
||||
"@tailwindcss/cli": "^4.0.14",
|
||||
"@types/lodash.merge": "^4.6.9",
|
||||
"@types/react": "^19.0.10",
|
||||
"@types/react-dom": "^19.0.4",
|
||||
"eslint-config-custom": "workspace:*",
|
||||
"fumadocs-core": "workspace:*",
|
||||
"next": "15.2.1",
|
||||
"tailwindcss": "^4.0.12",
|
||||
"next": "15.2.2",
|
||||
"tailwindcss": "^4.0.14",
|
||||
"tsc-alias": "^1.8.11",
|
||||
"tsconfig": "workspace:*"
|
||||
},
|
||||
|
||||
@@ -16,6 +16,8 @@ import {
|
||||
export interface OramaSearchDialogProps extends SharedProps {
|
||||
client: OramaCloudOptions['client'];
|
||||
searchOptions?: OramaCloudOptions['params'];
|
||||
index?: OramaCloudOptions['index'];
|
||||
|
||||
footer?: ReactNode;
|
||||
|
||||
defaultTag?: string;
|
||||
@@ -46,6 +48,7 @@ export default function OramaSearchDialog({
|
||||
defaultTag,
|
||||
showOrama = false,
|
||||
allowClear = false,
|
||||
index,
|
||||
...props
|
||||
}: OramaSearchDialogProps): ReactNode {
|
||||
const [tag, setTag] = useState(defaultTag);
|
||||
@@ -53,6 +56,7 @@ export default function OramaSearchDialog({
|
||||
{
|
||||
type: 'orama-cloud',
|
||||
client,
|
||||
index,
|
||||
params: searchOptions,
|
||||
},
|
||||
undefined,
|
||||
|
||||
Generated
+490
-499
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user