Client-Server Templates | Yext Hitchhikers Platform

book
Note
You must be on @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:

  1. _client.tsx
  2. _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 { PageContext } from "@yext/pages";
import { hydrateRoot } from "react-dom/client";

export { render };

const render = async (pageContext: PageContext<any>) => {
  const { Page, pageProps } = pageContext;
  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 "@yext/pages";

export const render = async (pageContext: PageContext<any>) => {
  const { Page, pageProps } = pageContext;

  return ReactDOMServer.renderToString(<Page {...pageProps} />);
};

export const replacementTag = "<!--YEXT-SERVER-->";

export const indexHtml = `<!DOCTYPE html>
  <html lang="<!--app-lang-->">
    <head></head>
    <body>
      <div id="reactele">${replacementTag}</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

book
Note
Refer to the SEO Best Practices reference doc for more information, examples, and best practices regarding management of your <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.