Overriding Component Layouts | Yext Hitchhikers Platform
What You’ll Learn
In this section, you will learn:
- How to override the layout of a Search component
- How to override the javascript of a Search component
Overview
Sites created with Jambo and the Hitchhiker Theme are heavily reliant on the Search Javascript Library (the Search SDK) built-in components. These components have our best practices and user experience in mind, and we don’t recommend deviating from those standards. However, if necessary, Jambo and the Theme together provide the following methods for accomplishing that:
- Changing the default CSS styling of a component
- Overriding only the Handlebars template for a built-in component.
- Overriding both the Javascript and Handlebars of a built-in component.
These are ranked in order of increasing implementation difficulty. The last two require some knowledge of the component’s internals in the SDK. As such, it may be difficult for an Admin to attempt them without the help of a Developer.
Setting the template Attribute of a Component
If the customer wishes to change the look of a particular component, and their requirements can’t be met with CSS alone, the next step is to override the component’s template attribute. The SDK provides a first-class way to supply each built-in component with a custom Handlebars template. It is documented in detail here. To make use of this hook in Jambo and the Theme, take these steps:
- Create the custom Handlebars partial you’d like the component to use as its template. Locate this in the partials directory.
- Using the jambo override command, create a shadow of the component’s script partial.
In this local shadow, there will be Javascript code, like the following, that computes a component’s configuration:
ANSWERS.addComponent(SomeComponent, Object.assign({}, { container: '.some-class-name', …, }, {{{ json componentSettings.SomeComponent }}}));
Add a line specifying the template attribute for the component:
ANSWERS.addComponent(SomeComponent, Object.assign({}, { container: '.some-class-name', template: `{{{read 'partials/my/new/template' }}}`, ..., }, {{{ json componentSettings.SomeComponent }}}));
When the jambo build command is executed, the built-in read Handlebars helper will inject the contents of the custom partials file into the template string.
As stated above, implementing this correctly requires knowledge of the component’s inner workings. Specifically, some of the component’s functionality may depend on the presence of a DOM element. By removing this element from the custom template or changing its ‘js-’ prefixed classname, that functionality could be broken.
Wholly Overriding a Component
If it’s desired to change the functionality of a built-in component, providing a different template will most likely not be enough. An entirely new, custom component may need to be supplied to the SDK. This component, when named correctly, will replace the built-in version. For reference, adding a custom component to the SDK is covered in detail here. The following will need to be done in the site repository:
- Create a custom Handlebars partial for the template. Locate this in the partials directory.
- Add a Javascript file to the partials directory. This file will need to specify a new class that extends ANSWERS.Component. As a starting point, it is recommended to use the Javascript of the built-in SDK component itself. This can then be modified to suit the customer’s needs. To override the built-in component in the SDK, the class must have the exact same type() method.
- To have the overridden built-in component use the Handlebars partial created in (1), follow the same steps listed in the section above.
Using the jambo override command, create a shadow of the scripts/core.hbs file. In the local shadow, there is this code block:
const JAMBO_INJECTED_DATA = {{{json env.JAMBO_INJECTED_DATA}}} || {}; const pages = JAMBO_INJECTED_DATA.pages || {}; const IS_STAGING = HitchhikerJS.isStaging(pages.stagingDomains || []);
Add the following lines immediately after:
{{> ‘partials/my/js/partial’ }} ANSWERS.registerComponentType(MyCustomClass);
Here, partials/my/js/partial is the custom Javascript template created in (2) and MyCustomClass is the class name used there.
Now, any addComponent calls for the built-in component will render the custom, overridden version. Because this approach requires writing Javascript, it should not be attempted by a Hitchhiker without the help of a Developer.
Coming up with the Javascript for an overridden component is a difficult task. To meet the client’s demands, and not break anything, a strong understanding of the SDK’s internals is required. For instance, custom components may often use the library’s global state or the search API. As such, a Developer may need to know how to access these things inside a component. One final complication is that the custom Javascript cannot include imports or requires. The SDK does not have a mechanism for bundling the dependencies of custom components.