CONNECT-platform

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:

1link$curl https://my-search.cloud?q=whatever would respond with something like: 1link${

2link$"results": [ 3link$ "https://johndoe.github.io/my-project/",

4link$"https://johndoe.github.io/my-project/docs/stuff", 5link$ "https://johndoe.github.io/my-project/docs/whatever/overview"

6link$] 7link$}

## linkStep 1: The Search Component

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

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

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

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

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

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

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

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

10link const query = new Subject();

16link https://my-search.cloud?q=${encodeURIComponent(q)} 17link ).pipe(catchError(() => of(undefined))) // --> no sweat in case of error 18link ), 19link map(res => 20link (res.results || []) 21link .map(url => url.substr(prefix.length)) // --> returned URLs must be relative to domain root 22link ), 23link share(), 24link ); 25link 26link return <ToCSearchBtn label="Search via my-search ..." query={query} results={results}/>; 27link} 28link 29link 30linkexport 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.

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
1linkimport { RendererLike } from '@connectv/html';

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

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

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

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

8linkimport { MySearch$} from './my-search'; // --> import the component 9link 10link 11linkexport function content(_content: HTMLElement, toc: HTMLElement, renderer: RendererLike<any, any>, file: File<string>) { 12link return ( 13link <Page title={config.page.title.extractor(_content, config, file)} 14link favicon={config.page.favicon} 15link meta={<Meta {...config.page.meta}/>} 16link fonts={<Fonts {...config.page.fonts}/>} 17link 18link scripts={config.page.scripts} 19link stylesheets={config.page.stylesheets} 20link 21link header={<Header {...config}/>} 22link footer={<Footer {...config}/>} 23link toc={ 24link <ToC search={<MySearch$/>}>{toc}</ToC> // --> give it to ToC for search