I'm trying to route users to a "locations" structure entry that normally has a URL structure that looks like: locations/<slug>

My client wants to use the structure of links from their old site to preserve SEO and wants to have the URL structure of: locations/<state>/<slug> where state is a 2 letter string. So, I'm trying to set up a route rule that just ignores the parameter and redirects to the regular route.

In routes.php I have the following rule:

'locations/<state:[a-z]{2}>/<slug:{slug}>' => 'locations/<slug>'

But when I try to hit a route (for example locations/ca/slug-name) I get an InvalidRouteException and an error message saying:

Unable to resolve the request "locations/slug-name"

So it looks like it's stripping out the state parameter successfully but I'm not sure why locations/slug-name isn't recognized as a valid route.

Is there something I'm missing? Is there an easier way to do this?

1 Answer 1


It sounds like you might be trying to blend Craft/Yii routing with Rewrites (if you're coming from an Apache background).

I believe what Craft interprets this as is an attempt to map a request to locations/or/my-entry-slug to the <slug> (literal) action of the locations controller (which doesn't exist).

If you just want to render a template for these entries, you can set up your route like this:

'locations/<state:[a-z]{2}>/<slug:{slug}>' => ['template' => 'locations/entry']

This way, you'll get a state and slug variable in the templates/locations/entry.twig template, with which you can look up the Locations Entry you want.

To troubleshoot further, we might need a bit more information about how your Locations Section is set up, and the goals for the route!

If you're just looking to capture and redirect legacy URLs, be sure and check out the Retour plugin.

Additionally (and for anyone who finds this in the future), I'd recommend reviewing the advanced routing docs.

  • Thank you! I had tried the ['template' => 'path'] method before but was trying to pass the slug in directly instead of pointing to the generic entry and loading the specific entry there. This worked perfectly!
    – slander
    Jan 10, 2019 at 16:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.