5

I've run into an issue that I can't seem to resolve. It should be possible to remove the preceding hashtag in routes by executing the steps provided in RouterConfiguration -> Options-> Push State.

I've executed all these steps, see the code below.

app.ts RouterConfiguration options

public configureRouter(config: RouterConfiguration, router: Router) {
    config.options.pushState = true;
    config.options.root = '/';
    config.map([
        {
            route: 'login',
            name: 'login',
            moduleId: 'pages/auth/login',
            nav: false,
            title: 'Login',
            settings: {
                allow_anonymous: true
            }
        }
    ]);
    ...

index.html head

<head>
  <meta charset="utf-8">
  <base href="/">
  ...

config.js

System.config({
  baseURL: "/",
  ...

My login route still only works using localhost:9000/#/login whereas localhost:9000/login can't be found. I've also tried implementing this in a fresh Aurelia JSPM skeleton application to no avail...

Any idea why this is happening and what I might be doing wrong?

Bryandh
  • 539
  • 1
  • 5
  • 22
  • 2
    I'll point someone from the router team to look at this. – Ashley Grant Aug 24 '17 at 15:19
  • What you are showing works fine for a long time for me, can you push up a repro with the fresh skeleton you mentioned? – PW Kad Aug 24 '17 at 15:39
  • @PWKad sure, here is the fresh Aurelia JSPM skeleton repo => https://github.com/bryandh/aurelia-routing-no-hash The welcome route only works when I enter `localhost:9000/#/welcome`. The route then visually changes to `localhost:9000/welcome` but when i physically refresh that page/route or navigate to the URL manually the route can't be found. – Bryandh Aug 25 '17 at 06:12
  • 1
    What you describe is a server configuration issue. For all your routes which normally follow after the `#`, you need to configure your server to serve the main `index.html`. The app is then bootstrapped and will handle the URLs `/welcome`. – Marc Scheib Aug 25 '17 at 18:24
  • @MarcScheib I used Express and didn't have to configure anything 0.o – 8protons Aug 25 '17 at 23:02
  • @8protons Probably it is configured ready to use for an SPA. Do you use some special package or express directly? Anyway, how should a server know to serve `index.html` on nearly all routes (except API)? It may configured as a fallback, however, normally you would expect a 404. Or your 404 redirect is the `index.html`. – Marc Scheib Aug 26 '17 at 10:39
  • How do I configure the server to accept there URLs then @MarcScheib ? I have configured JSPM to use the baseURL "/". – Bryandh Aug 28 '17 at 09:02
  • Which server are you using? – Marc Scheib Aug 28 '17 at 09:40
  • I'm running it locally with BrowserSync. – Bryandh Aug 28 '17 at 09:51

2 Answers2

1

For BrowserSync (as described by @Bryandh), you need to configure it to always fallback to your index.html. Depending on your project, you may have some task file(e.g. a Gulp serve task, which is used throughout Aurelia) which needs to be changed.

As an example, I took Aurelia's skeleton navigation project. It has a sub directory skeleton-esnext which uses Gulp and JSPM to run the application. In the file build/tasks/serve.js is a serve task which needs to be adjusted as follows:

var historyFallback = require('connect-history-api-fallback');

gulp.task('serve', ['build'], function(done) {
  browserSync({
    online: false,
    open: false,
    port: 9000,
    server: {
      baseDir: ['.'],
      middleware: [function(req, res, next) {
        res.setHeader('Access-Control-Allow-Origin', '*');
        next();
      }, historyFallback()]
    }
  }, done);
});

The important part is the historyFallback() middleware. This is provided automatically by BrowserSync. If you serve your app with this task now (gulp serve or gulp watch), you can directly access your routes, e.g. http://localhost:9000/users. There will be no more 404 as you get directed to index.html which bootstraps Aurelia and handles the route /users.

Marc Scheib
  • 1,963
  • 1
  • 24
  • 29
  • Thanks a lot, this works like a charm! I had absolutely no idea I could do this, appreciate your effort! – Bryandh Sep 01 '17 at 08:40
0

For my views that are being dynamically loaded into the router-view container, with index as the root, I was able to get my project's URLs to look like the following (which I believe is what you're asking for):

  • http://localhost:2112/
  • http://localhost:2112/jobs
  • http://localhost:2112/discussion

I didn't need to alter as much code as you shared in order to get this to work. The first thing I did was to establish a base reference in my root html file. For me, this was index.html.

<base href="/" />

Then, I set the push state to true inside the configureRouter() method

configureRouter(config, route) {
   ...
   config.options.pushState = true;
   ...
}
8protons
  • 3,591
  • 5
  • 32
  • 67
  • This is exactly as I described in my question, so this unfortunately doesn't really help me any further. – Bryandh Aug 28 '17 at 08:57
  • @Bryandh This answer is not "exactly as [you] described in [your] question". You have extraneous steps- I only wrote two lines of code to get this to work. You changed a significant more than simply two lines, including altering `config.js`, which may be causing your issue. I would advise you to start over and literally do what my answer suggests. Good luck. – 8protons Aug 28 '17 at 20:33