Paths and Slugs | Yext Hitchhikers Platform
This article outlines:
- How to define the paths for your pages using the
getPath
function - The
slug
field and how it works - The benefits of using the
slug
field for your paths and best practices - How the
slug
field is required for local development “dynamic mode”
Overview
The slug
field allows a user to define the “path” at which a page of their website is served. For example, if a page is served at www.yext.com/hello/world
, the slug would be hello/world
.
The slug helps to ensure that the paths for your web pages are URL-safe by performing validation and slugification for any inputted strings.
getPath Function
getPath
is a required function in your templates that returns a string. This string defines the path at which the page generated from that template is accessible in production.
Stream Templates
For Stream templates (i.e. pages generated from Streams), we highly recommend returning the slug
field. Refer to the example below:
export const getPath: GetPath<TemplateProps> = ({ document }) => {
return document.slug;
};
Technically, you can return any field (or combination of fields) from your Stream document to getPath
, but you must use the slug
field in order to test your paths during local development.
Static Templates
For static templates (i.e. individual pages that aren’t based on Stream documents), you can simply define your page path by returning a string. Refer to the example below:
export const getPath: GetPath<TemplateProps> = () => {
return `about`;
};
Slugs
Slug
is a field type that ensures your paths are always “URL-safe”. It accomplishes this by doing two things:
Validation: Validates when you attempt to publish a non URL-safe value
For example, here the Content throws an error because the input (“not url safe”) includes spaces.
A legal slug may only contain the following characters:
- Letters (i.e. any character from Unicode categories beginning with “L”)
- Numbers (i.e. any character from Unicode categories beginning with “N”)
- Any of the following characters:
( ) _ ~ : @ ; = / ’ $ * - . &
Slugification: Automatically “slugifies” embedded field references
It is extremely useful to include
embedded fields
as part of your slug (refer to the Embedded Fields module to learn more). This allows you to define your page paths based on fields from your entity data. In such scenarios, the slug field automatically converts each embedded reference into a URL-safe string!In the example below, the
slug
is defined as[[address.region]]/[[address.city]]/[[name]]
; assume that the underlying embedded fields evaluate toNY/New York/Turtlehead Tacos
. Theslug
dynamically converts this input tony/new-york/turtlehead-tacos
.Slugification Logic is defined as follows:
- Convert any uppercase letter to lowercase
- Replace any of
- ? #
with a space - Trim (i.e. remove any leading/trailing whitespace)
- Replace each set of one or more consecutive
whitespace characters
with
-
- Strip any illegal character
Benefits of Slug-Based Paths
It is highly recommended to define the paths for Stream-generated pages based on the slug
field, as opposed to other fields or hardcoded values. This practice offers two major benefits:
By defining paths solely based on the
slug
field, non-developer users have the ability to update production URLs by directly editingslugs
in the Content; no template-level code changes are required!It is required that you return the
slug
in yourgetPath
function to test your production paths during *local development*. The Pages system uses this field specifically to generate page paths during local development. If aslug
value is missing from one of your entities, you will not be able to preview that entity locally using “dynamic mode”.
Using an Alternate Slug Field in Local Development
As mentioned in the previous section, the Pages system uses the slug field for generating page paths during local development. If you would like to override this behavior, you can add a slugField
to your TemplateConfig
to reference an alternate slug field.
export const config: TemplateConfig = {
stream: {
$id: "locations",
fields: ["id", "name", "address", "c_alternateSlug"],
filter: {
entityTypes: ["location"],
},
localization: {
locales: ["en"],
},
},
slugField: "c_alternateSlug",
};
Disabling “Slug-Based” Local Dev URLs
By default, the npm run dev
command will automatically use the slug
field to generate your paths. However, you may have some entities for which the slug field is either not populated or not enabled on the entity type at all; and still want to test use these entities for local development.
If you are using a Yext starter, you can disable this behavior with the following command:
npm run dev -- --no-prod-url
This command will serve your local URLs in the following format, which will only be used locally and will not match what is served in production:
localhost:5173/[template-name]/[entity-id]
Slug Best Practices
To ensure your URLs are always in a clean state, please adhere to the following best practices. Failure to do so may result in page generation failures:
Ensure each entity in your stream has a
slug
value (in other words, ensure your slugs are nevernull
for an entity used to power a page in your site).In case of
null
values in your live production deploy, we recommend you configure a “fallback” path in yourgetPath
function. The starter templates for Pages projects contain sensible defaults like below for location entities.export const getPath: GetPath<TemplateProps> = ({ document }) => { return document.slug ? document.slug : `${document.locale}/${document.address.region}/${document.address.city}/${ document.address.line1 }-${document.id.toString()}`; };
Here we use the location’s
region
,city
, andaddress line 1
to create a unique path.
Ensure that your slugs do not begin with a forward slash (
/
). If your slug begins with a forward slash, this will cause the page to be served at an invalid URL.Ensure each
slug
is unique with respect to other entities used for your site. If any two pages in your site share the same path, both pages will fail to generate.