Redirects and URL Routing | Yext Hitchhikers Platform

Overview

URL routing, encompassing URL redirection and URL rewriting, is a powerful technique used to manage how URLs are handled and accessed within your site. It allows a single page or resource to be accessible through multiple URLs or paths, and also enables the dynamic modification of URLs based on predefined patterns. URL routing is essential for creating an efficient, user-friendly, and SEO-optimized website experience.

Common use cases for URL routing include:

  • Redirection: Redirecting users to a different page during site maintenance or downtime, or when navigating from outdated URLs to updated ones (e.g., redirecting from an old bookmarked link to the current page).
  • URL Shortening and Aliasing: Creating shorter, more memorable URLs (e.g., redirecting from /bob.html to /agents/US/NY/manhattan/bob.html) or aliasing URLs (like how maps.google.com redirects to google.com/maps ).
  • Rewriting: Internally mapping a URL to a different endpoint without changing the URL in the browser, which is useful for creating cleaner URLs or consolidating multiple pages under a single path.
  • Dynamic Routing: Utilizing placeholder and wildcard patterns to dynamically redirect or rewrite URLs based on matching rules, which is particularly powerful for large sites with numerous pages that follow similar URL structures.

With these capabilities, URL routing not only improves site navigation and user experience but also assists in maintaining the site’s structural integrity and relevance in search engine results.

Automatic Routing

The Yext Pages system also provides automatic rerouting when the slug field changes on an entity in the Yext platform (see the System-Generated Redirects ).

Route Configuration

Routing can be configured by developers in three different ways:

  1. File-based configuration: define staticRoutes and/or dynamicRoutes settings in config.yaml
  2. CSV: add a redirects.csv file to the root of the Pages repo
  3. Template-level redirects: define a getRedirects function in a template

File-Based Configuration in config.yaml

staticRoutes and dynamicRoutes provide configurations for URL redirects, supporting both individual path redirects and pattern-matching group redirects, with specified HTTP status codes indicating the nature of each reroute (redirect or rewrite).

Status Codes

The following status codes can be used when specifying redirects:

  • 301 (Moved Permanently)
  • 302 (Found)
  • 303 (See Other)
  • 307 (Temporary Redirect)
  • 308 (Permanent Redirect)

When creating a rewrite, you will specify status: 200. This indicates to the Pages serving system to serve the contents of the to path at the from path.

You can read more about HTTP status codes in this MDN reference doc .

Static Redirects

Static redirects and rewrites are used to forward or translate individual URL paths to individual destinations. This can be essential for a number of reasons such as creating redirects as part of a vendor migration where the URL structure changed requiring traffic to be redirected from old to new content, or creating friendly URLs for marketing purposes.

# Static redirects can establish redirects from individual source paths to
# individual destination paths.
staticRoutes:
  - from: /old-path
    to: https://www.yoursite.com/new-path
    status: 301 # 301 is the status code for a permanent redirect.

In this example, anyone visiting www.yoursite.com/old-path would be permanently redirected to https://www.example.com/new-path. The 301 status code tells the browser (and search engines) that the page has moved permanently, which is also beneficial for SEO as it passes the link equity to the new URL.

Static Rewrite

A static rewrite is used to internally map one URL to another without the URL changing in the browser’s address bar. This means the user sees the original URL they typed in, but the server serves the content from the rewritten path.

staticRoutes:
  - from: /user-friendly-url
    to: /internal-content-path/page1.html
    status: 200 # 200 status code means the content is served directly.

In the above static rewrite example, when a visitor goes to www.yoursite.com/user-friendly-url, the server serves the content from https://www.yoursite.com/internal-content-path/page1.html, but the URL remains www.yoursite.com/user-friendly-url in the visitor’s browser.

Dynamic Redirects & Rewrites

Dynamic routes are redirects and rewrites with placeholders and wildcards allowed in the source and destination URLs.

Placeholder Values

Placeholder values are used to create dynamic routes that capture parts of the incoming URL and reinsert them into the destination URL in a specified order. This allows for the creation of more adaptable and scalable routing logic.

dynamicRoutes:
  - from: /shop/:category/:productID
    to: /product/:productID/category/:category
    status: 302 # A temporary redirect status code

In this configuration, :category and :productID are placeholders for dynamic parts of the URL. The placeholders capture the relevant segments from the original URL and insert them into the new path.

For example, if someone accesses /shop/books/12345, the dynamic redirect would send them to /product/12345/category/books.

Wildcard Values

Wildcard values are indicated by an asterisk (*) and are useful for matching a sequence of path segments in the URL. They are particularly helpful when the exact path is not known in advance or when it is necessary to match a large number of URL patterns.

dynamicRoutes:
  - from: /articles/*
    to: /blog/:splat
    status: 302 # A temporary redirect status code

In the example provided, the wildcard * matches any sequence after /articles/. The :splat placeholder represents the sequence matched by the wildcard. For instance, a request to /articles/2023/march/spring-gardening-tips would dynamically redirect to /blog/2023/march/spring-gardening-tips.

You could also omit the :splat placeholder to route any URL that matches the sequence to an individual destination URL.

Dynamic Rewrites

A dynamic rewrite is like a dynamic redirect but without the URL change in the client’s address bar, creating clean and user-friendly URLs while serving the desired content.

dynamicRoutes:
  - from: /help/:articleName
    to: /support/content/:articleName
    status: 200 # The content is served without changing the URL.

With the above rewrite rule, when a user visits /help/installation-guide, the content from /support/content/installation-guide is served, but the URL stays as /help/installation-guide in the browser.

Add CSV File to Repo

You can add a redirects.csv file to the root of your repository to upload redirects in bulk. Your file should contain two columns:

  • Original URL (previous path)
  • Destination URL (new path)

Note that you should not add any column headers. Here is an example file:

/old-path,/new-path
/about.html,/about-v2.html

To host these redirects, deploy your site with this CSV file.

Note: if any collisions are detected on deploy (e.g., one source path redirects to two different destinations), the deploy will fail, and you will be notified to fix your file.

Entity-Level Redirects

Entity-Level Redirects in the Yext Pages system are designed to integrate directly with your entity data, allowing for the configuration of URL redirection within the specific context of your entity scopes and normal pages development. There are two primary methods to configure these redirects, each catering to specific developmental and operational needs:

Template-Level Redirects (src/templates)

Template-level redirects allow you to specify redirects directly within your src/templates files. This method is particularly useful for dynamically creating redirects based on the content or properties of individual pages.

Within your page template, you can utilize the getRedirects export to return an array of paths that are mapped to the path specified in getPath.

Advantages

  • Ideal for straightforward, page-specific redirects where each redirect leads directly from a specified source URL to the page being generated by the template
  • You can think of these as url aliases for your pages

Example

The example below redirects c_alias and c_previousAddress to the live page URL.

/**
 * src/templates/location.tsx
 * This template generates pages for location entities
 */
import {
  GetPath,
  GetRedirects,
  Template,
  TemplateProps,
} from "@yext/pages";

/**
 * Defines the set of entities to generate pages for.
 */
export const config: TemplateConfig = {
  stream: {
    $id: "location-pages",
    filter: {
      entityTypes: ["location"],
    },
    fields: [
      "id",
      "name",
      "slug",
      "c_alias",
      "c_previousAddress"
    ],
    localization: {
      locales: ["en"]
    },
  },
};

/**
 * Defines the path that the generated file will live at for production.
 */
export const getPath: GetPath<TemplateProps> = ({ document }) => {
  return document.slug;
};

/**
 * Defines a list of paths which will redirect to the path created by getPath.
 */
export const getRedirects: GetRedirects<TemplateProps> = ({ document }) => {
  return [
    document.c_alias,
    document.c_previousAddress 
  ];
};

Entity Redirect Sets (src/redirects)

book
Note
You must be on @yext/pages version 1.1.0-beta.6 or higher to use this feature.

An alternative approach is to configure redirects in your src/redirects directory. Files defined this directory allow you to generate redirects for sets of entities.

This is similar to how files defined in the src/templates directory allow you to generate pages for a set of entities; the main difference is that template files create HTML, while redirect files generate redirects.

Within these files, you can leverage the getDestination and getSources exports to fully customize your redirects as needed; particularly which paths should redirect, where they will redirect to, and what HTTP status code they should return.

Example

  • One obvious example of how this is useful is to host redirects for entities that have recently closed down (and therefore, their page URLs now 404); an entity redirect set can be used to redirect any closed entity page URLs to the home page
  • The config export sets the scope to a saved filter of entities called closed-locations.
  • In getSources, a 301 redirect is configured for each entity’s slug (e.g. page URL).
  • In getDestination, each source path is then mapped to index.html.

    /**
    * src/redirects/closed-locations.tsx
    * This file generates redirects for closed location entities
    */
    import {
      GetDestination,
      GetSources,
      TemplateConfig,
      TemplateProps,
    } from "@yext/pages";
    
    export const config: TemplateConfig = {
      stream: {
        $id: "closed-locations",
        fields: ["id", "name", "slug"],
        filter: {
          savedFilterIds: ["closed-locations"],
        },
        localization: {
          locales: ["en"],
        },
      },
    };
    
    /**
      * Defines the destination URL for all redirects configured in this file 
      * All getSources paths redirect to this value.
      */
    export const getDestination: GetDestination<TemplateProps> = ({ document }) => {
      return `index.html`;
    };
    
    /**
      * Generates source URL paths that will redirect to the URL in getDestination.
      * In this example, each source path is defined by each entity's slug value
      */
    export const getSources: GetSources<TemplateProps> = ({ document }) => {
      return [
        {
          "source": `${document.slug}`,
          "status": 301  // Indicates a permanent redirect
        },
      ];
    };

Considerations and Limitations

  • Only 3XX status codes can be specified in a getSources object
  • Each getSources.source must be a relative path; this path will be appended to your website when the redirect is hosted (e.g. a source of redirect-1 will be uploaded as [yourwebsite]/redirect-1)
  • Local development does not support testing for redirects; to test redirects, they must be deployed to the Yext platform. We recommend testing these on a staging/preview environment to ensure everything works as expected
    • You can validate that your redirects are being uploaded as expected on the deployments > page generation page; each path uploaded will be visible in the platform, along with the Stream JSON object that was used to generate that redirect.

Route Ordering

Routes are applied in the following priority order:

  1. Content & Serverless Functions
  2. Static Routes
  3. Dynamic Routes

This is best understood with a few examples.

Example 1

Let’s say you have a page served at locations/old-store-page and the following configuration:

staticRoutes:
  - from: /locations/old-store-page
    to: /locations/new-store-page
    status: 301

If a user navigates to your-brand.com/locations/old-store-page, the redirect WILL NOT occur because content is being served at your-brand.com/locations/old-store-page. Once you take down the old store page, the user will be redirected to the new store page.

Example 2

Take a look at the following configuration:

staticRoutes:
  - from: /locations/big-awesome-store
    to: /locations/flagship-store
    status: 301
dynamicRoutes:
  - from: /locations/*
    to: /stores/:splat
    status: 301

Since static routes take precedence over dynamic routes, a user visiting your-brand.com/locations/big-awesome-store will be redirected to your-brand.com/locations/flagship-store AND NOT your-brand.com/stores/big-awesome-store.