localize-router
localize-router copied to clipboard
Universal support for latest version of Angular
Hi, The example we have with universal is outdated as universal-cli has been deprecated , will it be possible for you to update the example or post a new repository with angular 5 and universal support. :)
Thank you ...!!
+1 need this
+1
I did this repo and use it as reference in my company : https://github.com/gilsdav/angular-universal-localize-router
@gilsdav , giving your work a shot. Will update you on the same :)
@gilsdav David, I tried your repository but its not changing URL while changing the language using button on UI for example I created two buttons of dashboard page and bind it with events like this
`
<button class="col-1-4" (click)="switchLanguage('en')">English</button>
<button class="col-1-4" (click)="switchLanguage('fr')">French</button>
<!-- events -->
switchLanguage(lang) {
this.localizeService.changeLanguage(lang);
}
`
Any work around or any fixes for this ?
Please check if #117 solves your problem
Hi @ranavc32, sorry for the inconvenience and thank's for your return. The problem was related to this issue. I downgraded router version to 5.2.6 for now. Check my repo again, I added your switchLang on dashboard page to test if it works.
Thanks @gilsdav . Will give it a try today :) and will update you.
Hi @gilsdav , So I gave this repository again a shot and everything works fine but only one thing I didn't understand in URL bar its still showing
http://localhost:4200/en/ROUTES.dashboard
So this ROUTES is still there in the URL, how can we just have
http://localhost:4200/en/dashboard
Any help will be appreciated. :)
Though while going through code I saw
export function createTranslateLoader(translate: TranslateService, location: Location, settings: LocalizeRouterSettings,) {
return new ManualParserLoader(translate, location, settings, ['en', 'fr'], 'ROUTES.');
}
Here you are passing ROUTES to the Manual parser.
So this problem got resolved when I passed '' to the ManualParser,
export function createTranslateLoader(translate: TranslateService, location: Location, settings: LocalizeRouterSettings,) {
return new ManualParserLoader(translate, location, settings, ['en', 'fr'], '');
}
Thanks for the solution @gilsdav . Really appreciate your work :)
Happy Coding :)
Hello @ranavc32 If it put "ROUTES.dashboard" in url this is because it doesn't find this translation in fr.json or en.json files. Take a look at my translation file https://github.com/gilsdav/angular-universal-localize-router/blob/master/src/assets/locales/fr.json . Indeed if you don't need an url translation orther than having the lang like "/fr/", you can remove prefix on ManuelPaserLoader. And thank's for your support :)
Repo updated for Angular 7 : https://github.com/gilsdav/angular-universal-localize-router
Hi @gilsdav I'hve wondering how you managed to make it work the repo https://github.com/gilsdav/angular-universal-localize-router for universal? I've mean, are you setting universal configuration behind the scenes? because I don't see any loader for node server side in that repo, I've tried to set that with my current application and after a lots of error the only that I've got is ERROR [Error] is very annoying.. if you have any idea that was can be happening please let me know. thank you!
Hello @BruneXX ,
Everything related to universal is it these files:
-
package.json all universal dependencies and usage of @gilsdav/ngx-translate-router (that is compatible with angular 8 and SSR). You will find all SSR build scripts too. The entry script is
npm run build:ssr
. - angular.json: need to add a project to point on all server entry files
- tsconfig.server.json: typescript config for server build and entry module
-
main.server.ts: to avoid some behaviors from
main.ts
- app.server.module.ts: enable server module and lazy-loading feature for ssr
- app.module.ts: specify that the app will be used with ssr (withServerTransition)
-
environment.ts: set the base URL to find locales (If you don't want to create your own manual loader for SSR (or use
UniversalTranslateLoader
) you have to use an absolute URL that start with "http://", "https://" and not with "/" because SSR doesn't have the origin to understand relative url). - server.ts: my ssr node server
-
webpack.server.config.js: used to package server and all it's dependences to be able to deploy it without
package.json
and without usingnpm install
command on server.
I think that's all.
I'm currently reviewing a PR that improve Readme for SSR: https://github.com/gilsdav/ngx-translate-router/pull/35/files Do not hesitate if something is not clear before the merge.
Regards
OK, thanks for the quick reply @gilsdav ! I've some things, I saw that:
- LazyUniversalModuleLoaderProvider is not longer used in app.server.module.ts, will be needed anyway?
- It's mandatory to use webpack.server.config.js in order this to work? because I'm not doing anything of that, I'm just using the default provided in angular.json for deploy.
- The server.ts that I'm using is the same as https://github.com/angular/universal-starter/blob/master/server.ts should that work or need to do some changes in order localize routes work?
- Also for locales, I'm using relative path, just '/assets/locales' not he environment behavior (anyway I've tried that, but did not solve my problem)
I've tried to integrate in the same you're doing in this repo: https://github.com/gilsdav/angular-universal-localize-router but I can't figured out, what's the difference with my own and why I'm getting that annoying ERROR [Error] in console with nothing else but that...
I've reviewed all those files you mentioned in your previous note, I've practically cloned the repo into mine, I've used meld to compare files and get all things wired up, but with no success yet.
Anyway, thanks for you help, I'll try to do this again from scratch checking each file you mention in the previous note and try to figured out what can be happening.
If you see something else that could be the culprit of that error just let me know, also the documentation here: https://github.com/Greentube/localize-router differs a bit from the: https://github.com/gilsdav/angular-universal-localize-router repo and I had to say that I saw some errors in that last one:
Here is an image with the error and some part of the URI that is not translated from the demo:
Thanks again for the quick response, appreciated!
Also reviewing the PR, something that is not clear to me at all is this code that AFAIK should be in server.ts: (Please correct me if I am worng)
app.get('/', ngApp);
data.locales.forEach(route => {
app.get(`/${route}`, ngApp);
app.get(`/${route}/*`, ngApp);
});
From where comes ngApp? I saw deeply in some other repo code, I think from this one: https://github.com/meeroslav/universal-localize-example/blob/master/src/server.ts, that is used as an aside function, but is that up to date? or should be reviewed to be included into the documentation? becuase including that funciton in my case was worst.. but I haven't seen some kind of that code in the https://github.com/gilsdav/angular-universal-localize-router repo.
Thanks!
- LazyUniversalModuleLoaderProvider is not needed anymore for Angular 8
-
ng add @nguniversal/express-engine --clientProject ...
command creates the webpack file - I don't think there is something particularly for Localize.
- relative url will not works on SSR so you have to implement a workaround for it. I prefer to use absolute url instead of other possibilities because we can quickly put our localization files on other assets server accessible by the client.
For errors:
- In can not reproduce the "home" path when "fr". How did you access to that ? Did you tried
- I didn't have implemented all the application (there is no "localize" pipe on this list)
For the locales.json
you can see I didn't implemented it in my project. I really recommend manualLoader. This workaround is if you really need to create "dynamic" languages.
Does your error only append in node console ?
Hi @gilsdav
- OK great!
- OK, I assume that's needed, right?
- OK.
- OK, I'll use full path from now
Errors:
- I've just cloned the repo, then executed
npm install
and thenng serve
just the usual.. - OK
Yes, I've realized that, I'll need to use dynamic languages.
Yes, It finish the compilation and serve the app, but when I go to the browser and just access to localhost:4200 or whatever route related to the app, the browser is hang on and that error appears in console and there's no more info, just that.
@BruneXX 2. This is needed in most cases (example: deployment on cloud provider) because you can only drop files. Without webpack post build you must have npm on the server and include the dev package.json into the package to be able to install dependences. Otherwise the application will not works on server (but will works locally).
Errors:
- Try with
npm start
to use the project instance of Angular-Cli (I personally always do that). I don't know your version but I tried with last version of Angular CLI and can not reproduce :/
Can you try with same version of all universal dependences than in my project into yours ?
@gilsdav About that, I'm using docker to get those things sorted, so may be that's not necessary. (I guess) because I've all dependencies needed inside the container.
Yes, I've also updated angular dependencies in package.json of your project, I'll give a try to discard that the error comes from there, but I'm pretty sure that is something related to the server.ts file I don't know why yet, but I think it comes from there, but as I saw there are no changes needed there, right? I had to apply some change in server.ts to add [domino] and some other globals, did you have some issues with that before?
@BruneXX
You can check const {AppServerModuleNgFactory, LAZY_MODULE_MAP} = require('./server/main');
.
The generated one (in my current CLI version) is const {AppServerModuleNgFactory, LAZY_MODULE_MAP} = require('./dist/server/main');
Check your DIST_FOLDER
too. I don't have any reference to "dist" in my repos:
- https://github.com/gilsdav/aa-universal-workshop/blob/done/server.ts
- https://github.com/gilsdav/angular-universal-localize-router/blob/master/server.ts
As you can see in the PR (new doc) you must set window.navigator.language = 'en';
(for "en" default lang) if you use [domino]
And finally if you add "node_Modules" into your .dockerignore
your image will be widely smaller. Its up to you to choose.
@gilsdav yep, I've realized about that too, but for me only works as is in: https://github.com/angular/universal-starter/blob/master/server.ts
const DIST_FOLDER = join(process.cwd(), 'dist');
const { AppServerModuleNgFactory, LAZY_MODULE_MAP } = require('./server/main');
I'll try to use that in your repo and check what happens.
PS: also another difference that I've found is that I'm not using import 'reflect-metadata';
in my repo. But I think that will not affect at the current behavior.
@gilsdav well well.. I've got the error :) something more explainatory I guess:
ERROR HttpErrorResponse { headers: HttpHeaders { normalizedNames: Map {}, lazyUpdate: null, headers: Map {} }, status: 0, statusText: 'Unknown Error', url: 'http://localhost:4200/assets/locales/en.json', ok: false, name: 'HttpErrorResponse', message: 'Http failure response for http://localhost:4200/assets/locales/en.json: 0 Unknown Error',
Now regarding this new issue is totally related with docker.. I need a way to map the container ip with the full path for routes, but I'm glad to say that it works!! thanks for all your help @gilsdav I've spent a lot of time trying to make this work and finally I've get it!
Best regards!
Hi @gilsdav I've a question regarding the languages that are set in the url, so for example: Is there a way in your package to set the language without add it in the url like this?
https://{domain}.com/es
https://{domain}.com/en
https://{domain}.com/fr
So I can set the route language at level component for example?
Thanks!
Hi @BruneXX, I'm not sure I clearly see your goal but I will try to be the more complete.
Default lang
As you can see in the documentation, the default lang will be automaticaly set with this logic: languageFromUrl || cachedLanguage || languageOfBrowser || firstLanguageFromConfig
.
So if you go to https://{domain}.com
the application will automatically redirect to https://{domain}.com/fr
using the previous logic.
Translate paths
You don't have to put the language into your paths because this.localize.translateRoute(...)
and | localize
will do it for you.
Do not translate url
You can use skipRouteLocalization
route option if you don't want to translate some urls.
Don't use prefix
You can use alwaysSetPrefix: false
option but I give no guarantee on it because I don't test it.
Keep in mind that if you change lang, the lang will be added to the URL. Only default lang can be removed from urls.
For me the main behavior of this library is to add the lang into URL (like Microsoft do https://docs.microsoft.com), and the second behavior is to translate each segments of the URL.
Hi @gilsdav Great explanation! My main concern is to not use the prefix, but there's no way to totally remove the /{lang} from url, right?
I was wondering to do that, in order to use a subdomain instead of an url "/{lang}" something like:
en.{domain}.com/my-route
es.{domain}.com/mi-ruta
but currently that's not possible since you told me in previous comment.
So may be we can report that as a new feature to improve (and may be add) the non-prefix behavior?
Thanks for all your help on this! :)
@BruneXX That's the deference between Angular I18n and ngx-translate.
- i18n: generate a dist by language to allow you to deploy it on deferent domains.
- ngx-translate: dynamic language loading to keep same domain.
localize-router and ngx-translate-router are only compatible with ngx-translate.