Skip to content

Routes and redirects

Routes created from the manager, stored in pb_routes. For everything a content editor needs to do without touching a file: move a page, retire an old address, point a URL at a template.

PageBlocks → Routes.

A row

FieldWhat it is
contextMODX context the route belongs to
methodHTTP method, GET by default
uriThe address, without a leading slash
typeWhat happens — see below
targetWhere it goes: a URL, a template, a chunk or a controller action
statusHTTP status for redirects. 301 by default
menuindexOrder, which decides who wins among equals
published_atAn unpublished route does not exist

Types

Typetarget isWhat happens
redirectA URLRedirect to it with status
redirect_controllerController@methodThe action's URL is resolved from the registered routes, then redirected to
controllerController@methodThe action handles the request
viewA MODX templateRenders that template
file_chunkA Fenom file under core/App/elements/Renders that file

redirect_controller exists so a redirect survives a change of address: you point at the action, and the URL is looked up at runtime. If the action cannot be resolved, the row is skipped rather than redirecting somewhere wrong.

301 by default, on purpose

A redirect entered by hand almost always means "this address has moved for good". 302 tells search engines the opposite and keeps the old URL in the index. Set 302 only when the move really is temporary.

Who wins

Routes come from two places — files and this table — so the order is fixed:

  1. Redirects win over everything for the same GET URI. A file route for that address is skipped, whether the redirect came from a file or from the table.
  2. Among redirects, the first one wins; duplicates for the same URI are dropped rather than crashing the dispatcher.
  3. For controller, view and file_chunk, file routes win. The table only fills addresses no file has claimed.

The third rule is what makes the table safe to hand to an editor: a row cannot quietly take over an address your code already serves.

A redirect does override your code

The first rule is the exception, and it is deliberate — retiring an address has to work even when something still answers there. If a working page suddenly redirects, look in this table before the routes directory.

Caching

The rows are read once and cached; the model clears that cache when a route is saved or deleted, so a change takes effect immediately.

A failed read — the table not migrated yet, the database briefly unavailable — is not cached. Otherwise a single bad moment during a deploy would freeze an empty route list until the next cache clear.

When to use a file instead

The table is for addresses. Anything with logic — conditions, parameters, access checks — belongs in core/App/routes/, where you can read it in a diff and test it. See Routing.

© PageBlocks 2019-present