# URL Patterns

A page group's URL pattern decides the address of each generated page. It is
set on the group's **General** page.

## Pattern syntax

A pattern is a path with one `{slug}` placeholder:

- `services/{slug}` produces `/services/new-york/`, `/services/london/`
- `products/detail/{slug}` produces `/products/detail/widget-pro/`
- `guides/{slug}-checklist` produces `/guides/seo-checklist/`

The pattern must contain `{slug}` exactly once; saving one with none or with
two fails. The placeholder is replaced by each row's `slug` value and matches
exactly one path segment, so a slug cannot contain a slash. Text before and
after `{slug}` in the same segment is allowed.

Leading and trailing slashes are ignored: `services/{slug}` and
`/services/{slug}/` behave the same. Requests match with or without a
trailing slash. Sitemap entries always end with one; a generated page's
canonical URL follows the trailing slash of the site's permalink structure.

## How a request is answered

Every published page group adds a WordPress rewrite rule for its pattern at
the top of the rule list, ahead of WordPress's own rules. When a request
matches a group's pattern, Rank:

1. takes the slug from the URL
2. looks the slug up in the group's cached rows, source by source in order,
   while WordPress parses the request
3. if a row is found, renders the group's base page with that row, applies the
   mappings, and points the page's canonical link and `og:url` at the
   generated URL
4. if no row is found, parses the request again without the page group rules,
   before WordPress queries posts or picks a template, so WordPress serves
   whatever else owns that URL, or its own 404 with a 404 status and the
   theme's 404 template

A generated page therefore takes precedence only for slugs that are in the
data. A real page or post at the same path as a generated one is hidden
behind it; every other URL the pattern happens to match keeps working.

Draft groups add no rule and answer nothing. A group whose data has not been
loaded answers no URL either, so every request falls through to WordPress.

Generated URLs need pretty permalinks (**Settings > Permalinks** set to
anything but Plain), because WordPress ignores rewrite rules otherwise. The
rules are rebuilt on the first request after a page group is created, changed
or deleted; `wp sleek rank flush-rewrites` rebuilds them at once. Deactivating
Rank removes them ([Deactivating](/docs/rank/activating.md#deactivating)).

## A pattern of only `{slug}`

A new group starts with the pattern `{slug}`, which matches every
single-segment URL on the site. Pages such as `/about/` keep working unless
their path is also a slug in the data, but every such request is first looked
up in the group's rows. Put the slug under a static path unless the group
really owns the top level of the site.

## Good practice

- Use a descriptive static path, such as `services/{slug}`, for both search
  engines and the rest of the site
- Keep slugs lowercase, hyphenated and URL-safe
- Do not let a pattern overlap existing pages whose paths could appear as
  slugs in your data; the generated page wins
