@mindbreeze.com/client-react is a React NPM library that provides the necessary functions to initialize an Insight App, perform search requests, and handle result responses. The library exposes a top-level InsightApp component for initialization, React hooks for search state management, result fetching, and rendering utilities for result properties.
Install using your preferred package manager:
# yarn
yarn add @mindbreeze.com/client-react
# npm
npm add @mindbreeze.com/client-react
For TypeScript support, install the types package. All types are available under the Mindbreeze namespace.
npm add @mindbreeze.com/client-types
import { Mindbreeze } from '@mindbreeze.com/client-types';
The package is hosted on AWS CodeArtifact. Follow these steps to configure access.
Create an IAM User and provide the User ID to the Mindbreeze team. The Mindbreeze team will add the user to the repository.
Once added, attach the following inline policy to the IAM user (Permissions tab → Add permissions → Create inline policy → JSON):
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": [
"codeartifact:GetAuthorizationToken",
"codeartifact:ReadFromRepository",
"codeartifact:GetRepositoryEndpoint",
"codeartifact:GetPackageVersionAsset",
"sts:GetServiceBearerToken"
],
"Resource": "*"
}]
}
Name the policy (e.g. MyCompanyCodeArtifactAccess) and click Create policy.
Run the following AWS CLI command to obtain an authorization token. The output is your authentication token.
aws codeartifact get-authorization-token \
--domain DOMAIN_NAME \
--domain-owner ACCOUNT_ID \
--region REGION \
--profile your-user-profile \
--query authorizationToken \
--output text
Add the following to your project’s .npmrc file, replacing CODEARTIFACT_TOKEN with the token from the previous step:
@mindbreeze.com:registry=https://mindbreeze-349188031343.d.codeartifact.eu-central-1.amazonaws.com/npm/mindbreeze/
//mindbreeze-349188031343.d.codeartifact.eu-central-1.amazonaws.com/npm/mindbreeze/:always-auth=true
//mindbreeze-349188031343.d.codeartifact.eu-central-1.amazonaws.com/npm/mindbreeze/:_authToken=${CODEARTIFACT_TOKEN}
The root component that initializes the Mindbreeze client and provides context to all child components. All application components must be rendered as children of InsightApp.
type Props = {
mindbreezeUrl: string; // URL to the Mindbreeze client service
mindbreezeRequire?: any; // Existing Mindbreeze Require instance
applicationOptions?: any; // Options passed to the application on init
loadStyles?: boolean; // Load Mindbreeze styles. Default: false
scriptUrl?: string; // Path to client.js. Default: /apps/scripts/client.js
}
Note: Either mindbreezeUrl or mindbreezeRequire must be provided.
const mindbreezeUrl = process.env.NEXT_PUBLIC_MINDBREEZE_URL || "";
<InsightApp
mindbreezeUrl={mindbreezeUrl}
applicationOptions={{ startSearch: true, _sources: [] }}
>
<SearchContent />
</InsightApp>
Returns the core Mindbreeze context including the client web components and application provider. Use this hook to access lower-level APIs or pass context to other hooks.
const { clientWebComponents, applicationProvider, application } = useMindbreeze();
Manages search state and exposes search actions. Returns a tuple of SearchState and SearchAction.
export const useSearch = (
clientWebComponents: any,
applicationProvider: ApplicationProvider | null,
options?: UseSearchOptions
) : [Mindbreeze.SearchState, Mindbreeze.SearchAction]
export type UseSearchOptions = {
firstPageNumber?: number; // Starting page number (e.g. 1)
maxPageCount?: number; // Maximum number of pages to return
count?: number; // Number of results per page
constraints?: any; // Additional search constraints
};
SearchState {
searchModel: any;
computing: boolean; // true while a search request is in-flight
estimatedCount: number; // Total estimated result count
pageCount: number; // Total number of pages
pageNumber: number; // Current page number
pageSize: number; // Results per page
}
setPage(page: number): void; // Navigate to a page
setPageSize(size: number): void; // Change results per page
setUnparsedUserQuery(input: string): void; // Update the search query
Fetches search results and tracks loading state.
export const useResults = (
clientWebComponents: any,
applicationProvider: ApplicationProvider | null,
options?: Mindbreeze.ResultControllerOptions
) : ResultInfo
type ResultInfo = {
results: Mindbreeze.ResultProperties[]; // Array of result objects
computing: boolean; // true while fetching
};
A complete search page with a search bar, results list, and pagination. Child components consume useMindbreeze to access the context provided by InsightApp.
export const SearchContent = () => {
const { clientWebComponents, applicationProvider } = useMindbreeze();
const [searchState, searchAction] = useSearch(
clientWebComponents, applicationProvider,
{ firstPageNumber: 1, maxPageCount: 100 }
);
const handleSearch = (event: any) => {
searchAction.setUnparsedUserQuery(event.target.value);
};
return (
<>
<SearchBar onSearch={handleSearch} placeholder="Search..." />
<Results />
<Pagination
selectedPage={searchState.pageNumber}
total={searchState.estimatedCount}
pageSize={searchState.pageSize}
pageSizeOptions={[5, 10, 15, 20, 50, 100]}
onSizeChanged={(size) => searchAction.setPageSize(size)}
onPageChanged={(page) => searchAction.setPage(page)}
/>
</>
);
};
Renders search results using useResults. The ResultPropertyRendering and DefaultRenderContext classes handle property rendering.
export default function Results() {
const { applicationProvider, clientWebComponents } = useMindbreeze();
const search = useResults(clientWebComponents, applicationProvider, {
requestedProperties: { actions: { formats: ['PROPERTY'] } },
});
const renderer = new ResultPropertyRendering();
const ctx = new DefaultRenderContext();
return (
<div>
{search.computing && <Spinner />}
{search.results.map((result) => (
<h3>{result.title.render(ctx, renderer)}</h3>
))}
</div>
);
}
Extend DefaultHTMLRenderer to customize how result properties, actions, and text extracts are rendered.
class MyRenderer extends DefaultHTMLRenderer {
renderNamedAction(context: RenderContext, action: PropertyAction) {
if (action.valueType === 'link') {
return <Button onClick={() => window.open(action.href)}>{action.label}</Button>;
}
return null;
}
renderTextExtracts(context: RenderContext, textExtracts: TextExtracts) {
const item = textExtracts.items[0];
return <Card><div>{item.propertyName}</div>
{this.renderTextExtract(context, item.value) as ReactNode}</Card>;
}
renderTextExtract(context: RenderContext, textExtract: TextExtract): ReactNode {
if (textExtract.typeName === "textsnippets") {
return <div>{this.renderStructuredText(context, textExtract.content) as ReactNode}</div>;
}
}
}
Render result actions within a result item:
const renderer = new MyRenderer();
const ctx = new DefaultRenderContext();
{result.actions && <div>{result.actions.render(ctx, renderer)}</div>}