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.
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 thedefault
. - 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 thebody
. When using arender
function thegetHeadConfig
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.
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
- Export
render
instead of a default export. render
should return full HTML document as a string instead of just the TSX body.- Props to the
render
function are the same as props to TSX component. getHeadConfig
does not work when using a non-React templating.getPath
is the same between React and non-React template approaches.