Star

MIT License
Copyright © 2020
CONNECT-platform

linkRecipe: Custom Search API

For this recipe, we're going to assume that we've got a nice search API that gives you a JSON array of URLs of matching documentation pages, based on a given query, and now we want to use it instead of the GitHub search for our docs.

We are assuming that the API, when requested with:

1curl https://my-search.cloud?q=whatever

would respond with something like:

1{

2 "results": [

3 "https://johndoe.github.io/my-project/",

4 "https://johndoe.github.io/my-project/docs/stuff",

5 "https://johndoe.github.io/my-project/docs/whatever/overview"

6 ]

7}


linkStep 1: The Search Component

Lets create a search component in .codedoc/content/my-search.tsx:

.codedoc/content/my-search.tsx
1import { ajax } from 'rxjs/ajax';

2import { Subject, of } from 'rxjs';

3import { switchMap, map, catchError, share } from 'rxjs/operators';

4import { RendererLike, ComponentThis } from '@connectv/html';

5import { transport } from '@connectv/sdh/transport';

6import { ToCSearchBtn } from '@codedoc/core/components';

7

8

9export function MySearch(this: ComponentThis, options: SearchOptions, renderer: RendererLike<any, any>) {

10 const query = new Subject();

11 const prefix = 'https://johndoe.github.io/my-project';

12

13 const results = query.pipe(

14 switchMap(q =>

15 ajax.getJSON(

16 `https://my-search.cloud?q=${encodeURIComponent(q)}`

17 ).pipe(catchError(() => of(undefined))) // --> no sweat in case of error

18 ),

19 map(res =>

20 (res.results || [])

21 .map(url => url.substr(prefix.length)) // --> returned URLs must be relative to domain root

22 ),

23 share(),

24 );

25

26 return <ToCSearchBtn label="Search via my-search ..." query={query} results={results}/>;

27}

28

29

30export const MySearch$ = /*#__PURE__*/transport(MySearch);


touch_app NOTE

Note that although we have defined the component MySearch, we also export a transported version of it named MySearch$. The reason is MySearch is a client-side component, i.e. it should be rendered and bound on the browser. However, we want to feed it to the rest of our layout components on the server-side, i.e. when we are building the HTML files. MySearch$ basically acts as a placeholder for MySearch in server-side code, allowing you to include it where you need it. When included, it will cause the code for the client-side component, i.e. MySearch, to be included in codedoc bundle, alongside an initialization script that would render MySearch in place of the placeholder on the browser.

Learn More

linkStep 2: Use MySearch

Now lets configure our ToC to use MySearch$ instead of the default GithubSearch$ component. For that purpose, we just need to modify .codedoc/content/index.tsx:

.codedoc/content/index.tsx
1import { RendererLike } from '@connectv/html';

2import { File } from 'rxline/fs';

3import { Page, Meta, ContentNav, Fonts, ToC } from '@codedoc/core/components';

4

5import { config } from '../config';

6import { Header } from './header';

7import { Footer } from './footer';

8import { MySearch$ } from './my-search'; // --> import the component

9

10

11export function content(_content: HTMLElement, toc: HTMLElement, renderer: RendererLike<any, any>, file: File<string>) {

12 return (

13 <Page title={config.page.title.extractor(_content, config, file)}

14 favicon={config.page.favicon}

15 meta={<Meta {...config.page.meta}/>}

16 fonts={<Fonts {...config.page.fonts}/>}

17

18 scripts={config.page.scripts}

19 stylesheets={config.page.stylesheets}

20

21 header={<Header {...config}/>}

22 footer={<Footer {...config}/>}

23 toc={

24 <ToC search={<MySearch$/>}>{toc}</ToC> // --> give it to ToC for search

25 }>

26 {_content}

27 <ContentNav content={_content}/>

28 </Page>

29 )

30}

Recipe: Custom Search APIStep 1: The Search ComponentStep 2: Use MySearch

Home Overview CLI Theme

Markdownchevron_right
Code Featureschevron_right

Images & Assets

Configurationchevron_right
Customizationchevron_right