[Vuejs]-How to configure symfony to work with Vue.js in HTML5 History mode

1👍

Had the Same issue. Symfony is simultaneously delivering a Vue driven frontend and implementing an Rest-API. I solved it using some sort of PageNotFound-Fallback, so basically every route that was not found by the Symfony Router will be forwarded/redirected to the Frontend. So the FrontendController looks like this:

class FrontendController extends Controller{

  public function indexAction(Request $request)
  {
    $base=$request->getBaseUrl();
    return $this->render('default/index.html.twig',['basePath'=>$base]);
  }


  public function pageNotFoundAction()
  {
    return $this->forward('AppBundle:Frontend:index');
  }
}

With an additional configuration in the routing.yml (see: Redirect with Event Listener for all "No route found 404 Not Found – NotFoundHttpException")

pageNotFound:
path: /{path}
defaults: { _controller: AppBundle:Frontend:pageNotFound, path: '' }
requirements:
    path: .*

Finally, the VueRouter needs to be configured, so it keeps the correct environment, simply by adding the base Property in the Router constructor. If the frontend component is not displayed correctly, you can use router.push('some-route') to manually adjust it.
Keep in mind that there will be no more 404 Errors, since they are all forwarded to the frontend, which can lead to bad scenarios using ajax on page load…
Altough it feels like a hack, I hope this helps. Open for better solutions.

EDIT Symfony version 3.4.3, Vue version 2.5.1

👤Laurin

3👍

For those who prefer using annotations [Symfony 3.x, 4.x]

You could use the following Routing in Symfony.

class DefaultController extends Controller
{
/**
 * @Route("/", name="homepage")
 * @Route("/{route}", name="vue_pages", requirements={"route"=".+"})
 */
    public function indexAction(Request $request)
    {
        return $this->render('default/index.html.twig', []);
    }
}

And In VueJS, you can Vue-Router to display a 404 page for routes not found via a wildcard as shown below,

import '...'; // import required components
export default new Router({
    mode: 'history',
    routes: [
        {
            path: '/',
            name: 'homepage',
            component: home
        },
        {
            path: '/hello',
            name: 'hello',
            component: hello
        },
        {
            path: '*',           // wildcard
            name: 'notfound',
            component: notfound
        }
    ]
});

You could check this Reference tutorial and the source code for a step-by-step setup.

Tested with Symfony 3.x, 4.x, VueJS 2.5.x, VueRouter 3.x

Leave a comment