Modules | Yext Hitchhikers Platform

Modules in PagesJS allow you to write React components and serve them at a public URL so that they can be injected via a <script /> tag to any HTML page.

This is very useful in scenarios where you want to create visual components that display API data from other products, such as Reviews, on external web pages hosted externally to Yext. Developers can hook into the existing Pages infrastructure to develop and test modules locally, and deploy them to our global CDN using our Git-basedCI/CD pipeline and serving layer.

book
Note
You must be using @yext/pages": "1.1.0” or greater to utilize this feature.

Getting Started

To create a new module in your PagesJS repo, run the following command:

npx @yext/pages@latest scaffold modules

To run your new module locally, run the following command:

npm run dev -- --module your-module

Your new module will now be running at http://localhost:5173/modules/your-module.

Deploying Your Module

To add your module to an HTML page, you first need to deploy your code.

book
Note
If your repo is not already tied to a Pages site, you will need to create a new site.

Once your site finishes building, you should see the module at a unique URL in the Pages Generation screen:

Deploy Details page showing module as URL

Adding Your Module to a Page

You can now add your module as a <script /> to the HTML of your page:

  <head>
    <!-- other head tags -->
    <script
      type="module"
      src="https://your-pages-domain.com/modules/your-module.umd.js"
    ></script>
  </head>

And you can reference the module in the body of the HTML by referring to the ID of the module:

<div id="your-module"></div>

Folder Structure

Running the modules scaffolding command generates the following folder structure in your PagesJS repo:

β”œβ”€β”€ src/modules
β”‚   β”œβ”€β”€ your-module
β”‚   β”‚   β”œβ”€β”€ your-module.tsx
β”‚   β”‚   └── postcss.config.js  // if you choose to use Tailwind CSS
β”‚   β”‚   └── tailwind.config.ts // if you choose to use Tailwind CSS
β”‚   β”‚   └── index.css
  • A modules folder will be generated within the src folder of your project.
  • A sub-folder with the name of your module is added within the module folder.
  • your-module.tsx contains the React component that will be served at a public URL.
  • index.css contains the styling for your module.
  • tailwind.config.ts and postcss.config.js will be added to your project assuming you choose to style your module with Tailwind CSS.

Response Headers

When you ran the scaffold command, a new responseHeader was added to your config.yaml:

responseHeaders:
  - pathPattern: ^modules/your-module.*
    headerKey: Access-Control-Allow-Origin
    headerValues:
      - "*"

This header is required to prevent CORS issues when loading your module as a script on a webpage.

Developing Modules

The TSX file should have a default export of a React component like so:

const YourModule: Module = () => {
  return(
    <AnalyticsProvider 
      templateData={templateData}
      productionDomains={["REPLACE_ME"]}
    >
      <div className="tw-YourModule">
        Module
      </div>
    </AnalyticsProvider>
  )
}

export default YourModule;

Code Reusability

You SHOULD NOT place any files in your module folder that are not generated by the scaffold command.

If you want to reuse components or functions from other locations (e.g. src/components) you can import them for use in your module. You can also use components from external libraries:

import { AnalyticsProvider } from "@yext/pages-components";
import SearchExperience from "../../components/search/SearchExerience";

const YourSearchModule: Module = () => {
  return(
    <AnalyticsProvider 
      templateData={templateData}
      productionDomains={["REPLACE_ME"]}
    >
      <div className="tw-YourSearchModule">
        <SearchExperience />
      </div>
    </AnalyticsProvider>
  )
}

export default YourSearchModule;

Styling

The styling of your module is isolated to the folder it is in. This means that the styling defined in the root of your PagesJS repo won’t impact the module and vice-versa. In addition, the styling of your module will not impact any of the styling of the page it is added to.

This is enabled by using a specific tailwindcss-scoped-preflight plugin in the tailwind.config.ts code. This is automatically set up when scaffolding a module with tailwind styling.

FAQs

Q. Can I add the same module twice on one page?

A. No. Since modules are referenced by their ID and HTML requires unique IDs for each element, a module can only be used once per page.

Q. Can I access the window object from my module?

A. Yes. Modules have access to the window object of whatever page they are added to. This allows you to access things like query parameters in the URL.

Q. Can I utilize serverless functions in conjunction with modules?

A. Yes. You can deploy serverless functions alongside your modules and call them from your module code. This is useful if you want to include something like form submission in your module. You can hide your API key from the browser by wrapping the submission logic in a serverless function.