Ngx-admin: HTML 5 Routing

Created on 23 Sep 2016  路  26Comments  路  Source: akveo/ngx-admin

Sort of a bug, but more of a feature request.

What is the effort to convert links to HTML 5 routes versus hash routing? Angular recommends using HTML 5 routing over hash routing. Has routing also does not appear to work with auth0 although I am seeking support from them for help.

When I set hash routing to false in app.routing.ts:

export const routing = RouterModule.forRoot(routes, { useHash: false });

The initial page will load, but all links will be broken.

help wanted needs investigation

All 26 comments

Have you tried changing the LocationStrategy?

Maybe try going to src/app/app.module.ts and adding the following import:

import { PathLocationStrategy, LocationStrategy } from '@angular/common';

and then add the following line to the APP_PROVIDERS

{ provide: LocationStrategy, useClass: PathLocationStrategy },

Links don't work because they do not take the location strategy into account.

Here's the culprit (theme/components/baMenu/baMenu.service.ts):

      let itemUrl = this._router.serializeUrl(this._router.createUrlTree(object.route.paths));
      object.url = object.url ? object.url : '#' + itemUrl;

And later in the same file:

  protected _selectItem(object:any):any {
    object.selected = object.url == ('#' + this._router.url);
    return object;
  }

As you can see, the hash is hardcoded. You can try removing it (simply replace it for an empty string) and see if that fixes menu links.

Removing the hash in the menu service certainly fixed the links. However, there still seems to be an issue with the routing, as clicking on any links results in a 404 error. The 404 is only visible in the developer tool console, the browser viewport itself is blank.

Could you please provide the URL that causes 404? Is it when you reload the page?

It may be a problem with the server not sending index.html when the route doesn't match any static file

All of the URLs cause an error.
When I first load the page "http://localhost:8080/", the address bar changes to "http://localhost:8080/pages/dashboard"
If I try to refresh the page, it remains blank and the console indicates there are 404 errors.

It is definitely a problem with webpack because it tries to load the path you want - /pages/dashboard, and it doesn't find that directory on your disk, so it outputs a 404.

You can alleviate this by specifying historyApiFallback in the webpack's configuration. Details can be found here.
As it's mentioned there, try setting it to true, and if it doesn't work specify your _index.html_ file explicitly there.

Hey All, yes, unfortunately HTML5 routing is not supported at the moment out of the box. If you could provide a PR making a complete support that would be awesome. Thanks in advance.

Unfortunately, I am too new to Angular/TypeScript/Webpack, etc. that I am not versed enough to figure some of this out. The things I tried do not work.

@gregkopp have you tried setting historyApiFallback, as I mentioned?

I tried various combinations of setting that as well as the other options mentioned. Now I get errors like this:

Cannot GET /pages/tables/basictables

When trying to navigate away from the dashboard.

I will try to look into this in detail soon.

I have same issue.

When I set hash routing to false in app.routing.ts to support HTML5 routing:
export const routing = RouterModule.forRoot(routes, { useHash: false });

I do not see error 404 but see following error:

<% if (webpackConfig.htmlElements.headTags) { %> <%= webpackConfig.htmlElements.headTags %> <% } %>
<% if (webpackConfig.metadata.isDevServer && webpackConfig.metadata.HMR !== true) { %> <% } %>

any help?

@Kamalswami, I had same problem and solved it by configuring webpack-dev-server to proxy all paths to itself, to root path (/):

proxy: {
    '/**': {
        target: 'http://localhost:3000',
        secure: false,
        pathRewrite: { '^/.*': '' }
    }
},
historyApiFallback : false,

You'll need to change localhost port (3000) to port that you use.

Hey, thanks for this discussion I believe it's definitely worth merging into the project.
@DavorLovric if you would be able to provide a PR I guess everyone would be happy!

@DavorLovric in production app we could have different api which should be proxied and rewrite all paths isn't good enough

devServer: {
    contentBase: path.resolve("./dist"), // to look in into built folder
    port: 8080,
    historyApiFallback: {
        index: "/index.html" // our main .html file
    },
    proxy: {
        "/api": {
            target: "http://localhost:3000",
            secure: false
        }
    },
}

@AndreiShostik if you have specific api that you want to proxy to somewhere else, you can add proxy definition for that before catch-all path definition:

proxy: {
    "/api": {
        target: "http://google.com",
        secure: false
    },
    '/**': {
        target: 'http://localhost:3000',
        secure: false,
        pathRewrite: { '^/.*': '' }
    }
},
historyApiFallback : false,

Anything that starts with /api will be handled by first proxy rule, and everything else by second one.
(historyApiFallback is not useful as it makes webpack-dev-server return raw (unprocessed) file, so if there is some server-side code in it, it is not executed before file is returned. - As @Kamalswami experienced.)

Would this work for your setup?

@nnixaa thx for the invitation to join the project, I'll do it over the weekend! :)

For me, the historyapifallback fixed the 404 problems.

The main issue that I am facing is that the links work, but they do a hard refresh, reloading the entire page.

This also happens in the production build (I've hosted it on firebase which already has rewrites and also in a local express).

Can anyone provide some input on this?

@catalintoma I didn't dive deep into that but first working solution for me was:
add (click)="navigate(menuItem.url)" to https://github.com/akveo/ng2-admin/blob/3f2670f5c22e70550ffe48ab80d69658511f0da4/src/app/theme/components/baMenu/components/baMenuItem/baMenuItem.html#L4
and in component.ts file add simple logic

public navigate(url) {
    this.router.navigate([url]);
    return false;
}

@AndreiShostik
You are right, this fix works.

But this should not be required, I've read the ng2 docs and it says that html5-style of routing works out of the box.

What I've done is not serialize the url and just keep the routes as on array on the bMenuItem (prepared in the baMenu.service)
After that, I've used the router-link directive.

Since the problem is reproducible in production, I still need to figure out why is it not working out of the box.

Hi guys! We just fixed this issue and now all works properly. Could you check it on your side and let us know if it works fine.

Hey @Tibing

I've just tested it and it works perfectly.

Thank you!

Awesome, closing it then, let us know if there any issues.

@AndreiShostik when you say add to line 4 do you mean like this?
(click)="navigate(menuItem.url){{ menuItem.title }}

@elviro fixed my [[link](https://github.com/akveo/ng2-admin/blob/3f2670f5c22e70550ffe48ab80d69658511f0da4/src/app/theme/components/baMenu/components/baMenuItem/baMenuItem.html#L4)]

hi everyone , any one can send me a code of ng2-admin with HTML 5 Routing , i tried very much but unable to convert in html 5 routing .... please share a complete code of ng2-admin.
i will be very thanks full to him. .

Was this page helpful?
0 / 5 - 0 ratings

Related issues

tal-shahar picture tal-shahar  路  3Comments

queirozfcom picture queirozfcom  路  4Comments

xandatspain picture xandatspain  路  3Comments

burtonator picture burtonator  路  3Comments

nsankaranarayanan picture nsankaranarayanan  路  3Comments