chrisguttandin / angular-prerender

A command line tool to prerender Angular Apps.
MIT License
125 stars 7 forks source link

Feature request: add support for `--exclude-routes *` #125

Open bl9l opened 3 years ago

bl9l commented 3 years ago

Hi.

I'm using @gilsdav/ngx-translate-router. So I have to manualy exclude each route by adding it to --exclude-routes.

Is it possible to either add the support of wildcard exclude or the propper parsing that can handle localized routes?

chrisguttandin commented 3 years ago

Hi @bl9l,

can you please explain that a little further? I'm not familiar with the way @gilsdav/ngx-translate-router works. I had a look a the README and now I wonder if angular-prerender would be able to detect any of the translated routes at all. I guess the guess-parser (no pun intended :-)) can't detect the translations and will only pick up the default language. But maybe I'm wrong.

bl9l commented 3 years ago

It works like so:

For example I have this routes configuration

[{
  path: 'some-page',
  component: SomeComponent,
}]

And my app supports two langs en and ru.

Now I need to localize the URL of the page with SomeComponent. In my template I'm using:

<a [routerLink]="['/some-page'] | localize">SomePage Link</a>

It generates different routerLink depending on which language is selected and how it is localized. It generates http://app.url/en/some-page-localized for the selected en lang and http://app.url/ru/локализованная-страница for ru. And original URL http://app.url/some-page is not available anymore. But angular-prerender can not detect this replacement and keeps on detecting original route /some-page.

Speaking of how this lib replaces the original URLs with localized ones - i don't know :)

chrisguttandin commented 3 years ago

Thanks for the clarification. Just to be sure I understood this correctly. You want angular-prerender to render /en/some-page-localized and /ru/локализованная-страница and the original route /some-page should not be rendered, right?

Could you please set up a little example project based on your example? I think that would make it far easier to add this feature and we could also use it as basis for adding an integration test to the test suite.

bl9l commented 3 years ago

Hello again. Sorry for 10 days delay. Here it is. https://github.com/bl9l/router-prerender-example . Just run npx angular-prerender to see the errors.

chrisguttandin commented 3 years ago

Thanks a lot for providing the example project. That was really helpful.

I'm afraid there is no way to detect the localization of the routes which happens in the templates. angular-prerender uses the guess-parser to get all the routes. And that parser works by traversing the TypeScript files to get the routes.

In case of your example these routes will be:

/some-page
/another-page

What do you think about adding an option to angular-prerender to specifiy the JSON file with the translations?

npx angular-prerender --ngx-translate-router-config src/assets/en.json

The result would then be that angular-prerender renders the english routes:

/some-page-localized
/another-page-localized

Would something like that work for you?

Do you know if there is a way to programmatically use the translation logic of ngx-translate-router or would we need to reimplement that?

bl9l commented 3 years ago

That's unfortunate. I didn't think about how Angular stores its routes tree and in order to parse it we need to parse ts files instead of the compiled url tree. Damn lazy modules :D.

Anyway. In order to work around ngx-translate-router we have to provide more information about routes. Something like this:

npx angular-prerender --ngx-translate-router-config ./ngx-translate-router-config.json

ngx-translate-router-config.json:

{
  "prefix": "ROUTES",
  "files": [
    "src/assets/en.json",
    "src/assets/ru.json",
    "src/assets/fr.json"
  ]
}

What do you think?

chrisguttandin commented 3 years ago

Ah you mean instead of running angular-prerender for each language it should better render all languages at once?

One thing that will not work though is any extra configuration as described here: https://github.com/gilsdav/ngx-translate-router#excluding-routes The guess-parser doesn't extract the data object of a route so far.

bl9l commented 3 years ago

If the data object of a route contains skipRouteLocalisation: true, I guess, its localization will not be presented in any of the localization files also. So I think it doesn't mater.

chrisguttandin commented 3 years ago

Hi @bl9l, sorry for the long delay.

I just submitted a PR to your test-case which implements a route process plugin. These are plugins used by Scully to pre-process the routes before the rendering starts. I added support for them today. I'm trying to enable Scully plugins for angular-prerender anyway and thought they come in handy here as well.

What do you think?