Client-Server Templates | Yext Hitchhikers Platform
@yext/pages version 1.0.0 or higher to use this feature.
Overview
PagesJS handles rendering for your project via built-in defaults. However, you can optionally customize how your page templates render on both the client and server via the following entry-point files in your src/templates directory:
_client.tsx_server.tsx
Client Template
The client template allows you to control how your page templates render on the client (i.e. a web browser).
This template must export a render function. Refer to the code snippet below:
// src/templates/_client.tsx
// Using React 18
import * as React from "react";
import * as ReactDOM from "react-dom/client";
import { PageContext } from "../types.js";
export { render };
const render = async (pageContext: PageContext<any>) => {
const { Page, pageProps } = pageContext;
ReactDOM.hydrateRoot(
document.getElementById("reactele")!,
<Page {...pageProps} />
);
};Server Template
The server template allows you to control how your page templates render on the server.
This template must export a render function. Refer to the code snippet below:
// src/templates/_server.tsx
// Using React 18
import * as React from "react";
import * as ReactDOMServer from "react-dom/server";
import { PageContext } from "../types.js";
export const render = async (pageContext: PageContext<any>) => {
const { Page, pageProps } = pageContext;
return ReactDOMServer.renderToString(<Page {...pageProps} />);
};
export const getReplacementTag = async () => {
return "<!--YEXT-SERVER-->";
};
export const getIndexHtml = async () => {
return `<!DOCTYPE html>
<html lang="<!--app-lang-->">
<head></head>
<body>
<div id="reactele">${await getReplacementTag()}</div>
</body>
</html>`;
};PageContext
In both templates, it is necessary that you import PageContext and pass that to the render functions. This is an interface from @yext/pages that provides your render templates with information about each page template being rendered, as well as its props (document, __meta, path, relativePrefixToRoot, etc.).
This should be imported as such:
import { PageContext } from "@yext/pages";Refer to the interface below, and to the
@yext/pages documentation
for more information about the TemplateRenderProps interface:
export interface PageContext<T extends TemplateRenderProps> {
/** The props injected into the template */
pageProps: T;
/** The template to render */
Page: Template<T>;
}HTML <head> Tag Configuration
<head> tags.
The _server.tsx file can be used to configure a global <head> element for each template in your project. This should be used to store global <head> information.
To provide custom configuration for the <head> tag on a per-template basis, you should utilize the getHeadConfig export in each of your src/templates. Per template, Pages will merge the contents of getHeadConfig with the global configuration in _server.tsx.
If your project does not utilize the _server.tsx and _client.tsx files, only the configuration provided via getHeadConfig will be used, per the PagesJS rendering defaults.