Search code examples
routespolymerweb-component

Polymer/web components <app-router> Cannot GET/<route>


I'm using Polymer for an app and using Erik Ringsmuth's app-router for routing. The code is as follows:

In index.html:

<app-router mode="pushstate">
  <app-route path="/" import="/elements/login-page/login-page.html"></app-route>
  <app-route path="/dash" import="/elements/dash-page/dash-page.html"></app-route>
  <app-route path="/new" import="/elements/newapp-page/newapp-page.html"></app-route>
  <app-route path="*" import="/elements/dash-page/dash-page.html"></app-route>
</app-router>

In login-page.html:

<link rel="import" href="../../../bower_components/polymer/polymer.html">

<polymer-element name="login-page" attributes="">
  <template>
    <link rel="stylesheet" href="login-page.css">
    <section vertical layout center-center>
      <h1>Login with:</h1>
      <fire-login provider="github"></fire-login>
      <fire-login provider="facebook"></fire-login>
    </section>
  </template>
</polymer-element>

The other pages are similar. Everything works fine out of the box but when I refresh any of the pages I get a Cannot GET /dash or Cannot GET /new. Going back to the root path and refreshing gets everything going again.

I can't figure out why refreshing doesn't work.


Solution

  • You are expecting more magic from this component than it could provide :)

    The requests are going to HTTP server, not directly to the <app-router> component. You are using HTML5 pushState way of handling routes. That said, when you specify /new as new path, the component shows the desired import and substitutes the location.href with http://youserver/new. On the other hand, when you press F5, the browser is being redirected to http://youserver/new. Sounds like different actions, right?

    So, the request to http://youserver/new is being handled by your web server and since there is no such page, you get 404.

    You have two options here:

    • teach your HTTP server to handle /new as your_router_page.html with mod_rewrite or like;
    • specify the proper path in <app-route>s.

    The component-way (IMHO) is to specify the proper path:

    <app-route path="/my-router.html?/dash"></app-route>
    

    Or even better get stuck to hash-like navigation, since it works out of the box and requires no specific route handling at all. The pushState is more like to handle redirects to outside of the current component handler.

    Hope it helps.