Step 1: Approach

There are two places a developer could choose to execute their own custom logic - server-side or client-side. Our goal is to support both places. There are various advantages and disadvantages to each:

Server-Side Client-Side
More Secure - doesn’t require publishing sensitive API keys client-side Better Latency - invoking a function server-side will add latency to the Search API
Analytics and Logging - we can log all of the functions and their responses Loading State - allows developer to implement a loading state for subsequent API calls, creating a better UX and reducing the time to contentful paint

Whether a developer is implementing logic server-side or client-side, they will use query rules to trigger their logic. This means that they can choose to trigger logic using all of the criteria that we currently support - like regular expressions and string matching - as well as more powerful, NLP-powered criteria coming in the future.

Depending on whether the developer wants to run the code server-side or client-side, they can use one of two new query rules actions:

  • USE_FUNCTION: This runs a Typescript function from a Yext plugin on our servers and forwards the return value to the front-end.
  • RETURN_CUSTOM_DATA: This simply returns a static JSON blob that is used to signal to the front-end that it’s supposed to trigger an action, like redirecting to a URL or fetching data on the client-side.

    In addition to triggering actions, custom data could also be used for display. For example, you could write the content for promotions in the back-end as JSON blobs, but then write the display and styling on the front-end.

Putting it all together, the architecture looks like this:

query rules functions architecture

Next let’s dive into both of these new actions in query rules.