3

I'm using Craft as the backend for an app and VueJS along with Element API to deliver the content.

Everything so far is working sweet, except when I try to pull up the detail page for an entry because in Craft, the route doesn't exist.

To be clear, my main listing page and links work but if I try to visit http://localhost/slug/id directly, I get a 404.

I know within the context of something like Laravel, I could do

Route::any('{all}', function () {
    return view('index');
})
->where(['all' => '.*']);

Is there something similar I could do with Craft?

I should add I have user registration and aspects that vue can't handle because Craft doesn't have a full crud api.

7

To pull this off, first you’ll have to make sure all of your Element API endpoints begin with something consistent, like api/ or data/, etc.

Then create a route in craft/config/routes.php that will match everything besides those Element API endpoints:

<?php

return array(
    '(?!api\/).*' => 'index'
);

'index' is the template path the requests should be routed to, so tweak that if needed.

If you have any other routes defined in there, make sure they go before this one.

I should add I have user registration and aspects that vue can't handle because Craft doesn't have a full crud api.

You can use the same controller actions the Control Panel uses. There are a few examples, including user registration at the bottom of the templating docs.

If you want to keep these handled by custom pages, you’ll need to add routes for them in routes.php, or else they will stop working due to that new catchall route. Craft only attempts its default behavior of matching the URI to a public template as a last resort; if a route matches the URI, that route will take precedence.

  • ah, looks like that'll burst the Element API endpoints though, do I have any other options? – Steven Grant Mar 5 '17 at 18:17
  • looks like the way around this is to do post/(?P<slug>[^\/]+)\/(?P<number>\d+) - ideally I'd like to drop post but this will do for now – Steven Grant Mar 6 '17 at 17:36
  • @StevenGrant Ah, right. Just updated the route example to ignore Element API endpoints (assuming you can give all your endpoints a consistent prefix, e.g. api/). – Brandon Kelly Mar 6 '17 at 18:09
  • Looks like I jumped the gun a little here. Despite having the route example you've given, I'm still managing to 404 when I try visit any URL other than the home page or the API endpoints. – Steven Grant Apr 13 '17 at 23:09
  • Do you have an index template? (index.html or index.twig) – Brandon Kelly Apr 14 '17 at 12:19
6

In case someone uses Craft 3, this should work:

<? return array( '<url:(?!api\/).*>' => ['template' => 'index'] );

2

Not sure why Davids solution doesn't work for me, I'm using the following (Craft 3.2.8):

return [
    '<url:(?!api\b)\b\w+>' => ['template' => 'index'],
];

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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