URL routing — encompassing URL redirection and URL rewriting — is a powerful technique for managing 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 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 include:
- Redirection: Redirecting users 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.htmlto/agents/US/NY/manhattan/bob.html) or aliasing URLs (like howmaps.google.comredirects togoogle.com/maps). - Rewriting: Internally mapping a URL to a different endpoint without changing the URL in the browser, useful for creating cleaner URLs or consolidating multiple pages under a single path.
- Dynamic Routing: Using placeholder and wildcard patterns to dynamically redirect or rewrite URLs based on matching rules — particularly powerful for large sites with numerous pages following similar URL structures.
System-Generated Redirects
The Yext Pages system automatically generates redirects in response to URL path updates for your live pages. Any time a template powered by a stream has its data change for a given page, the following happens:
- The page is republished at the new path.
- A redirect is automatically created from the old path to the new path — which is crucial for both SEO and user experience.
Example
-
A brand has a location entity powering a live page at
locations.brand.com/nyc. The page path is powered by theslugfield, which is set tonyc.
- You update the slug field from
nyctomanhattan. - Once the update is made in the Knowledge Graph, Yext republishes the live page at
locations.brand.com/manhattanand automatically creates a redirect from/nycto/manhattan. - When a visitor requests
/nyc, they are redirected to/manhattan.
Developer-Configured Routing
Routing can be configured by developers in three ways:
-
File-based configuration — define
staticRoutesand/ordynamicRoutesinconfig.yaml -
CSV — add a
redirects.csvfile to the root of the Pages repo -
Template-level redirects — define a
getRedirectsfunction (orgetSources/getDestinationinsrc/redirects) in a template
File-Based Configuration in config.yaml
staticRoutes and dynamicRoutes support both individual path redirects and pattern-matching group redirects, with HTTP status codes indicating the nature of each reroute.
Status Codes
For redirects, the following status codes can be used:
- 301 (Moved Permanently)
- 302 (Found)
- 303 (See Other)
- 307 (Temporary Redirect)
- 308 (Permanent Redirect)
For rewrites, specify status: 200. This tells the Pages serving system to serve the contents of the to path at the from path.
See the MDN HTTP status code reference for more detail.
Static Redirects
Static redirects forward individual URL paths to individual destinations — useful for vendor migrations where URL structure changed, or for creating friendly marketing URLs.
staticRoutes:
- from: /old-path
to: https://www.yoursite.com/new-path
status: 301
In this example, anyone visiting www.yoursite.com/old-path is permanently redirected to https://www.yoursite.com/new-path. The 301 status code tells browsers and search engines the page has moved permanently, passing link equity to the new URL.
Static Rewrites
A static rewrite internally maps one URL to another without changing the URL in the browser's address bar. The user sees the original URL, but the server serves content from the rewritten path.
staticRoutes:
- from: /user-friendly-url
to: /internal-content-path/page1.html
status: 200
When a visitor goes to www.yoursite.com/user-friendly-url, the server serves content from /internal-content-path/page1.html, but the URL stays as /user-friendly-url in the browser.
Dynamic Redirects
Dynamic routes are redirects and rewrites with placeholders and wildcards allowed in the source and destination URLs.
Placeholder Values
Placeholders capture parts of the incoming URL and reinsert them into the destination URL in a specified order.
dynamicRoutes:
- from: /shop/:category/:productID
to: /product/:productID/category/:category
status: 302
:category and :productID capture the relevant segments from the original URL and insert them into the new path. A request to /shop/books/12345 redirects to /product/12345/category/books.
Wildcard Values
Wildcards (*) match any sequence of path segments and are useful when the exact path isn't known in advance.
dynamicRoutes:
- from: /articles/*
to: /blog/:splat
status: 302
The * matches any sequence after /articles/. The :splat placeholder represents the matched sequence. A request to /articles/2023/march/spring-gardening-tips redirects to /blog/2023/march/spring-gardening-tips.
You can also omit :splat to route any matching URL to a single destination.
Dynamic Rewrites
A dynamic rewrite works like a dynamic redirect but without changing the URL in the browser.
dynamicRoutes:
- from: /help/:articleName
to: /support/content/:articleName
status: 200
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 a CSV File to the Repo
You can add a redirects.csv file to the root of your repository to upload redirects in bulk. The file should contain two columns — original URL (previous path) and destination URL (new path) — with no column headers:
/old-path,/new-path /about.html,/about-v2.html
Deploy your site with this CSV file to host the redirects.
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 the file.
Entity-Level Redirects
Entity-level redirects integrate directly with your entity data, allowing redirect configuration within the context of your entity scopes and normal pages development. There are two primary methods:
Template-Level Redirects (src/templates)
Template-level redirects let you specify redirects directly within your src/templates files, dynamically creating redirects based on the content or properties of individual pages.
Use the getRedirects export to return an array of paths that map to the path specified in getPath. These act as URL aliases for your pages.
/**
* src/templates/location.tsx
*/
import {
GetPath,
GetRedirects,
Template,
TemplateProps,
} from "@yext/pages";
export const config: TemplateConfig = {
stream: {
$id: "location-pages",
filter: {
entityTypes: ["location"],
},
fields: [
"id",
"name",
"slug",
"c_alias",
"c_previousAddress"
],
localization: {
locales: ["en"]
},
},
};
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
];
};
In this example, both c_alias and c_previousAddress redirect to the live page URL.
Entity Redirect Sets (src/redirects)
Note: You must be on
@yext/pagesversion1.1.0-beta.6or higher to use this feature.
An alternative is to configure redirects in your src/redirects directory. Files in this directory generate redirects for sets of entities — similar to how src/templates files generate pages for a set of entities. The key difference: template files create HTML, redirect files generate redirects.
Use the getDestination and getSources exports to fully customize which paths redirect, where they redirect to, and what HTTP status code to return.
Example: Redirecting closed location pages to the home page
/**
* src/redirects/closed-locations.tsx
*/
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 in this file.
*/
export const getDestination: GetDestination<TemplateProps> = ({ document }) => {
return `index.html`;
};
/**
* Generates source paths that will redirect to the URL in getDestination.
*/
export const getSources: GetSources<TemplateProps> = ({ document }) => {
return [
{
"source": `${document.slug}`,
"status": 301
},
];
};
The config export scopes to a saved filter of closed location entities. Each entity's slug (its former page URL) redirects with a 301 to index.html.
Considerations and limitations:
- Only
3XXstatus codes can be specified in agetSourcesobject. - Each
getSources.sourcemust be a relative path — it will be appended to your website when hosted (e.g., a source ofredirect-1becomes[yourwebsite]/redirect-1). - Local development does not support testing redirects. To test, deploy to the Yext platform — a staging/preview environment is recommended. You can validate uploaded redirects on the Deployments > Page Generation page, where each path and its stream JSON object will be visible.
Route Ordering
Routes are applied in the following priority order:
- Content & Serverless Functions
- Static Routes
- Dynamic Routes
Example 1
If a page is being served at locations/old-store-page and you have:
staticRoutes:
- from: /locations/old-store-page
to: /locations/new-store-page
status: 301
A user navigating to your-brand.com/locations/old-store-page will not be redirected — because content is being served at that path. Content takes priority over static routes. Once the old store page is taken down, the redirect will take effect.
Example 2
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 is redirected to your-brand.com/locations/flagship-store — not your-brand.com/stores/big-awesome-store.