Extend engine definitions
Extend engine definitions
This is for:
DeveloperTypically, when using server-side rendering (SSR) with Coveo Headless, you would fetch the static state as follows:
const staticState = await engineDefinition.fetchStaticState();
and you would hydrate it as follows:
const hydratedState = await engineDefinition.hydrateStaticState({
searchAction: staticState.searchAction,
});
However, you may sometimes need to access the engine and controllers before the initial search is executed during fetchStaticState
, or before the initial search gets simulated during hydrateStaticState
.
Coveo provides three utilities for these situations:
-
build
-
fetchStaticState.fromBuildResult
-
hydrateStaticState.fromBuildResult
Build the engine and controllers
You can build an engine and its controllers directly from an engine definition by calling your engine definition’s build
as follows:
const { engine, controllers } = await engineDefinition.build();
If you need to initialize the engine with a slightly different configuration than the one inherited from your engine definition, you may extend
it as follows:
const { engine, controllers } = await engineDefinition.build({
extend(options) {
return {
...options,
logFormatter() {
// ...
},
};
},
});
Fetch the static state
Internally, the fetchStaticState
method does five things:
-
It initializes an engine.
-
It initializes controllers.
-
It executes a search and waits for it to finish.
-
It returns
searchAction
. This is an action which, when dispatched, is equivalent to re-executing the search and getting the same response. -
It returns a copy of the state of every controller.
If you want to access the engine and controllers, you can use build
, which effectively replaces steps 1 and 2.
You can then use fetchStaticState.fromBuildResult
, which effectively replaces steps 3 to 5.
const { engine, controllers } = await engineDefinition.build();
const staticState = await engineDefinition.fetchStaticState.fromBuildResult({
buildResult: { engine, controllers },
});
Hydrate the static state
Internally, the hydrateStaticState
method does four things:
-
It initializes an engine.
-
It initializes controllers.
-
It dispatches the
searchAction
given to it. -
It returns the engine and controllers it initialized.
If you want to access the engine and controllers, you can use build
, which effectively replaces steps 1 and 2.
You can then use hydrateStaticState.fromBuildResult
, which effectively replaces steps 3 and 4.
const { engine, controllers } = await engineDefinition.build();
const staticState = await engineDefinition.hydrateStaticState.fromBuildResult({
buildResult: { engine, controllers },
searchAction,
});
Keep the server and client aligned
If you choose to manipulate the engine or controllers before passing them to fromBuildResult
, this could effect the state that’s returned by whichever fromBuildResult
was called.
For this reason, we recommend that you extract any manipulations you do to your engine into a separate function.
You can then use it for both fetchStaticState.fromBuildResult
and hydrateStaticState.fromBuildResult
, as in the following code samples.
In common/engine-definition.ts
:
import {
defineSearchEngine,
defineSearchBox,
defineResultList,
defineFacet,
getSampleSearchEngineConfiguration,
loadQueryActions,
SearchCompletedAction,
} from '@coveo/headless-react/ssr';
const engineDefinition = defineSearchEngine({
configuration: getSampleSearchEngineConfiguration(),
controllers: {
searchBox: defineSearchBox(),
resultList: defineResultList(),
authorFacet: defineFacet({ field: "author" }),
sourceFacet: defineFacet({ field: "source" }),
},
});
async function getBuildResult() {
const buildResult = await engineDefinition.build();
const { updateQuery } = loadQueryActions(buildResult.engine);
buildResult.engine.dispatch(updateQuery({ q: "I like trains" }));
return buildResult;
}
export async function fetchStaticState() {
return engineDefinition.fetchStaticState.fromBuildResult({
buildResult: await getBuildResult(),
});
}
export async function hydrateStaticState(options: {
searchAction: SearchCompletedAction;
}) {
return engineDefinition.hydrateStaticState.fromBuildResult({
buildResult: await getBuildResult(),
searchAction: options.searchAction,
});
}
Don’t export engineDefinition . |
|
Extract your logic to obtain the build result. | |
Export your own customized version of fetchStaticState . |
|
Export your own customized version of hydrateStaticState . |
In server.ts
:
import { fetchStaticState } from './common/engine-definition.ts';
// ...
const staticState = await fetchStaticState();
// ...
Your server code isn’t polluted with with a lot of complex logic. |
In client.ts
:
import { hydrateStaticState } from './common/engine-definition.ts';
// ...
const hydratedState = await hydrateStaticState({
searchAction: staticState.searchAction,
});
Avoid doing something like the following code samples. In
In
In
|