Not sure of this is intentional or a bug but, when we add a route using Settings -> Routes in the CMS, routes.php does not work. I guess maybe its due to us using a wildcard and this takes presedence over routes.php

The route we needed to add in the CMS was:


The reason we need a wildcard is because I don't want to hard code the page slug as this could be changed by a website administrator which would break functionality.

I added it in the CMS Routes because I can't find out how to add a wildcard in routes.php (perhaps worthy of another question as I would like that answer too!).

in the meantime I have to use routes.php and hard code the slug URLs as follows for each locale:

'contact-us/<teamid>'         => ['template' => 'pages/index'],
'cysylltu-â-ni/<teamid>'         => ['template' => 'pages/index'],

It would be great if I could either: 1) Use the CMS routes with this wildcard AND routes.php still works for all my others, or 2) Add a wildcard in routes.php (my preference)


2 Answers 2


Since you use the routes.php, I think you will not need any custom route in the control panel. On the other side, you'll need something stronger to avoid (as Olivier Bon said) catching anything before your teamID.

Solution 1

Use a Single, then no user will be able to change your page slug

Solution 2

If you want to keep it that way, add a rule in your template to look if the param matches your target page (but the solution 1 is still better).

  • Solution 1 - i would rather avoid singles unless necessary and using them just to have a route in my opinion is not good. They are good for the home page but not for a standard page in my opinion. Also, I dont want to prevent the user changing the slug. If their SEO expert tells them to then fine, you should not stop slug renaming just because the system cant then link it to a template. Solution 2 - I dont get this one... the page says it cant find the template because I have not route for it, due to adding in a second segment. Commented Jan 28, 2019 at 9:49
  • I was using routes in the admin because I dont know how to add a wildcard in routes.php. And I see no other way than the system looking at every page to match the route to teamid, for any slug name. So the page mydomain.com/whateveryouwant/teamid can then be used. Commented Jan 28, 2019 at 9:50
  • [1/2] Single are for any page that you want to be like you want (no slug change, no delete, etc.) – We use it to create flexible archive page (ex: a blog page that you want to control, from the CP, any settings like "entry per page"). As for your issue, there's no wildcard in the routes.php becauce any <param> can be - if no validation is present - anything. But you'll need to be more specific if you dont want all second level page to matched your rule. Commented Jan 28, 2019 at 14:16
  • [2/2] More specific like that : ``` '<entrySlug:{slug}>/<teamid:\d{6}>' => ['template' => 'pages/index'], ``` This way, the rule will match ony if the first level is an craft element and if the second level is a 6 digits (replace the 6 by your own teamid length). Commented Jan 28, 2019 at 14:18
  • But you can add a wildcard * in the Routes in Admin, so the system interprets that somehow, so I assumed in routes.php there must be something to do the same. I also dont like using singles for what should be a standard page on the site. Yes for a blog listing, or home page, fine, but an About Us page or something that uses the same fields and templates as all other pages I dont like it. I also build the backend to be as easy as possible for customers to manage, and so I try to keep all pages in Pages. I also dont want to stop them changing the slug... they may want to changeit for SEO reasons Commented Jan 29, 2019 at 11:19

I don't know if it's great practice to do this but if you want a "wildcard", especially as your first segment, you should a) put it in your routes.php manually b) make it the last route (always) otherwise it will take precedence just as you said and the other routes won't work. Also, using regex in your named parameters is good practice, if you are sure that teamid> is always and only a number, you could do this <teamid:\d+> so that someone visiting contact-us/peanuts would get a 404.

As far as setting this catch all route you want, just use a named parameter again:

'<anything>/<teamid:\d+>'         => ['template' => 'pages/index'],

This would have your catch all effect and will allow you to fetch the first segment if you need to.

If you expect a certain format for this first segment, in your template by calling {{ anything }} you could do some sort of validation. Also you could use regular expression to narrow the possibilities down a bit... With this as is, 500shoes/54896 would return your index page...

Hope that helps :)


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.