Pure JS Rendering | Yext Hitchhikers Platform

Yext recommends using React as the templating language for your pages. However, under the hood you can use any JavaScript-based templating language you want on top of the Pages system. And best of all you can mix and match templating languages within one site!

Overall the repo structure and the general data flow are the exact same regardless of templating language. The main difference is that instead of exporting a TSX component as the default export, you should export a render function. Note: when not using a TSX component, your export should NOT be the default export.

light bulb
Note
Any templates that are written in pure JS will not support a live dev server with hot module reloading (HMR). This feature is limited to React at the moment. In order to preview your changes locally, you must build, generate, and serve locally. The pages CLI (instructions here ) will help with these commands - see the instructions for yext pages serve.


React

Here is an example of a template on React. As a reminder, we are exporting the default function.

import * as React from "react";
import { GetPath, Template, TemplateProps, TemplateRenderProps } from "@yext/pages";

const template: Template<TemplateRenderProps> = ({ document }) => {
  const { name, address } = document;
  return (
    <>
      <h1>{name}</h1>
      <div>
        <div>{address.line1}</div>
        <div>
          {address.city}, {address.region}
        </div>
      </div>
    </>
  );
};

// EXPORT DEFAULT FUNCTION
export default template;


Pure JS

Here is an example that doesn’t use React. There are a few things to notice:

  • We are exporting a render function (as a named export) instead of the default.
  • The render function takes the same props as the React template.
  • In this example, we are just using a JavaScript template literal to render the page.
  • The function is returning the full html document instead of just the body. When using a render function the getHeadConfig won’t work. Instead you should embed anything in the head directly in the return value.

    export const render: Render<TemplateRenderProps> = ({ document }) => {
      const { name, address } = document;
      return `    
        <!DOCTYPE html>
        <html>
          <head>
            <title>${name}</title>
          </head>
          <body>
            <h1>${name}</h1>
            <div>
              <div>${address.line1}</div>
              <div>
                ${address.city}, ${address.region}
              </div>
            </div>
          </body>
        </html>
      `;
    };
    // NO DEFAULT EXPORT
    


Handlebars

Because this is pure JS rendering you can use any templating language that supports JS. For example here is how you could use Handlebars as the templating language.

light bulb
Note
First you will need to install Handlebars with npm install handlebars.

Instead of using a template literal, we are compiling a Handlebars template and then using that to generate the HTML.

import * as hbs from "handlebars";

export const render: Render<TemplateRenderProps> = ({ document }) => {
  const hbsTemplateString = `    
    <!DOCTYPE html>
      <html>
      <head>
      <title>{{name}}</title>
      </head>
      <body>
        <h1>{{name}}</h1>
        <div>
          <div>{{address.line1}}</div>
          <div>
            {{address.city}}, {{address.region}}
          </div>
        </div>
      </body>
      </html>
    `;

  // Compile Template
  const hbsTemplate = hbs.compile(hbsTemplateString);
  // Render HTML
  return hbsTemplate(document);
};

// NO DEFAULT EXPORT


Recap

  1. Export render instead of a default export.
  2. render should return full HTML document as a string instead of just the TSX body.
  3. Props to the render function are the same as props to TSX component.
  4. getHeadConfig does not work when using a non-React templating.
  5. getPath is the same between React and non-React template approaches.
Feedback