Allow custom "outputPath" directory for each locale
🚀 Feature request
Command (mark with an x)
- [x] build
Description
New version of Angular CLI allows us to use the new --localize option to generate different locales. This is great as it significantly reduces the build time for apps with many languages. However, as far as I can tell, the name of the output directory for each language is set to the name of the locale. So if I have this locale defined:
"locales": { "foo-bar": { "translation": "src/i18n/messages.en-US.xlf" } }
the output directory for this locale would be /foo-bar.
Describe the solution you'd like
I would like to be able to specify outputPath per locale, ideally by just defining "outputPath" in each locale which would then be appended to existing build options outputPath.
Describe alternatives you've considered
Alternative is to just change name of the locale to the one I want. But this then creates a problem where LOCALE_ID is also changed. And I want my LOCALE_ID to be, for example en-US and my output directory of build to be /en.
I've run into the same issue and wonder if it wouldn't make more sense to simply follow the baseHref property if present?
My settings in angular.json:
"i18n": {
"sourceLocale": {
"code": "nl-BE",
"baseHref": "nl"
},
"locales": {
"fr-BE": {
"baseHref": "fr",
"translation": "src/i18n/messages.fr-BE.xlf"
},
"de-BE": {
"baseHref": "de",
"translation": "src/i18n/messages.de-BE.xlf"
},
"en-GB": {
"baseHref": "en",
"translation": "src/i18n/messages.en-GB.xlf"
}
}
},
I've resolved into adding a postbuild script to rename the output directories,
but this seems hacky at best.
const fs = require('fs');
const outputPath = './dist/public/';
const directories = fs.readdirSync(outputPath, {withFileTypes: true})
.filter(v => v.isDirectory())
.map(dir => dir.name);
directories.forEach(dir => {
try {
fs.renameSync(outputPath + dir, outputPath + dir.substr(0, 2));
console.log('\x1b[32m%s\x1b[0m', 'Successfully renamed the output directory ' + dir + ' to ' + dir.substr(0, 2));
}
catch (err) {
console.log('\x1b[31m%s\x1b[0m', err);
}
});
So a year have past and still you cannot specify your output directory per locale? I've ran into same problem, I don't need my directory to be en-US but us.
Can someone look into this? Solution provided by @delrueba does not works in every environment. Kubernetes mounted drives etc. Im guessing this does not require a lot of effort but it costing developers hours and hours
My problem: in my application the app locale is driven by browser cookie, because I don't want to expose the locale in app business URL. I need either this issue or https://github.com/angular/angular-cli/issues/17416 to be solved. But both are still open. So sad!
can Angular core team add this feature? I would appreciate if the folder name can follow the base-href (in which, pretty make sense).
Our application uses a similar approach as @tkt028 mentioned: we only set a cookie and let the server decide on the index template to serve. This means that per language, we need to generate a separate bundle. i've setup 2 configurations using localize at first until i noticed that the options "deployUrl" and "outputPath" are not available for the localized bundles. i tried again with a different approach:
// prod
"deployUrl": "/static/en/",
"outputPath": "build/en",
"i18nFile": "src/locale/messages.en.xlf",
"i18nLocale": "en",
// prod-de
"deployUrl": "/static/de/",
"outputPath": "build/de",
"i18nFile": "src/locale/messages.de.xlf",
"i18nLocale": "de",
but when i run these configurations using ng build --configuration=prod,prod-de, all js files end up in the same folder (=> build/de) and i only get the "de" index.html.
I hope the new feature request process is also for angular-cli https://blog.angular.io/new-feature-request-process-a9f69d106fc8.
am I right @mgechev ?
We'll initially enable it for the framework repository and if it is successful consider it for CLI and components.
Still not fixed? I want my default language setting in the root /dist folder and all the other locales in their seperate fodlers e.g. /dist/fr/... It builds wrongly, i can copy the files manually but when i use the ag-github-cli module i cant do it that way...
This is also needed for firebase deploys. To benefit from the full functionality of firebase, the directories need to be specific as in en_ALL, en_us, en_au etc. But this directory structure doesn't match the locale id required by Angular.
+1
Is there any update on this issue?
Still not fixed? I want my default language setting in the root
/distfolder and all the other locales in their seperate fodlers e.g./dist/fr/... It builds wrongly, i can copy the files manually but when i use the ag-github-cli module i cant do it that way...
I acheived this same requirement using separate builds. One build for default language, and another for all locales.
package.json:
"build": "npm run build.en && npm run build.localize",
"build.en": "ng build --configuration production",
"build.localize": "ng build --configuration production-localize",
For the locale build configuration, preserve output files.
angular.json:
"production-localize": {
"localize": [
"es"
],
"deleteOutputPath": false,
...
}
Had a quick chat with @clydin about this and our initial reaction is that we would like to keep the directory output of @angular-devkit/build-angular as stable and consistent as possible, a new outputPath option per-locale would complicate that. It would also be difficult for the Angular CLI to evolve its directory structure over time if we support options to place content anywhere.
Separately, we've been exploring making Angular builders more powerful and composable. We think this might be a better solution if we can can make them easy and accessible enough, @angular-devkit/build-angular could be left alone, and instead users could write a custom builder (or leverage an existing one built for this use case) to move files around to the structure they really want. This could be done to rename all the locales from replace - characters with _ (en-US -> en_US) or move the source locale to the root of dist/ with everything else under their own subdirectories. With a custom builder you could create basically any structure you wanted without being limited to the semantics of outputPath.
One other thing to keep in mind is that servers don't have to serve your Angular application according to the exact structure of dist/. It is quite common to have a server parse a user's cookie or some query parameter to choose a locale and then serve the Angular app under that locale, without exposing the locale as a URL path (https://foo.test/en/).
I'll leave this issue open until we have a concrete recommended solution to point to. You can do this with custom builders now, but composing an @angular-devkit/build-angular target is quite tricky and I understand why it is not an ideal solution right now. Hopefully improvements to this system will give more flexibility with output structure in the future.
Any update on this feature? We need this
So what is the recommended way to do this at the moment? I figured since Firebase is a Google product, the Angular team would have at least been consulted on how to make this seemless for the two....
What should the standard be for localized folders? en-US or en_us?
Should the language be in the URL? (I think no, it looks messy and it's a technically a different app).
Had a quick chat with @clydin about this and our initial reaction is that we would like to keep the directory output of
@angular-devkit/build-angularas stable and consistent as possible, a newoutputPathoption per-locale would complicate that. It would also be difficult for the Angular CLI to evolve its directory structure over time if we support options to place content anywhere.Separately, we've been exploring making Angular builders more powerful and composable. We think this might be a better solution if we can can make them easy and accessible enough,
@angular-devkit/build-angularcould be left alone, and instead users could write a custom builder (or leverage an existing one built for this use case) to move files around to the structure they really want. This could be done to rename all the locales from replace-characters with_(en-US->en_US) or move the source locale to the root ofdist/with everything else under their own subdirectories. With a custom builder you could create basically any structure you wanted without being limited to the semantics ofoutputPath.One other thing to keep in mind is that servers don't have to serve your Angular application according to the exact structure of
dist/. It is quite common to have a server parse a user's cookie or some query parameter to choose a locale and then serve the Angular app under that locale, without exposing the locale as a URL path (https://foo.test/en/).I'll leave this issue open until we have a concrete recommended solution to point to. You can do this with custom builders now, but composing an
@angular-devkit/build-angulartarget is quite tricky and I understand why it is not an ideal solution right now. Hopefully improvements to this system will give more flexibility with output structure in the future.
If the user specifies an outputPath on that particular locale, use that instead of the localecode. Is that really such a big change?
firebase deploys
+1 !!
Same problem here.