Core: /assets/i18n/en.json NOT FOUND

Created on 21 May 2018  路  17Comments  路  Source: ngx-translate/core

screen shot 2018-05-20 at 11 00 43 pm

I realize this is a common issue and have been scouring this repo's support tickets and Stackoverflow looking for why I can't get this working. None of the many suggestions I've tried have worked. I'm confused because my setup is simple and in no way (that I can see) different from the example code setup shared in this repo.

I'm using Angular 5.1.0 along with Angular CLI 1.7. Webpack and ngx-translate versions are as follows:

    "@ngx-translate/core": "^9.1.1",
    "@ngx-translate/http-loader": "^2.0.1",
    "webpack": "~3.8.1"

http://localhost:4200/src/assets/i18n/en.json resolves to the file correctly in the browser, so the file is in the correct location for the default configuration outlined in the ngx-translate README.

Here are the relevant files:

app.component.ts

import { ActivatedRoute } from '@angular/router';
import { Component, ElementRef, HostListener, OnInit, ViewChild, AfterViewInit, ErrorHandler } from '@angular/core';
import {TranslateService} from '@ngx-translate/core';

/*
 * Main app component that houses all views.
 */
@Component({
  selector: 'app-comp',
  templateUrl: './app.component.html'
})

export class AppComponent {

  store: any;

  constructor(private route: ActivatedRoute, private translate: TranslateService) {
    // translate.addLangs(['en', 'fr']);
    translate.setDefaultLang('en');
  }
}

app.module.ts

import { MaterialModule } from './material.module';
import { BrowserModule, Title } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { TranslateModule, TranslateLoader } from '@ngx-translate/core';
import { TranslateHttpLoader } from '@ngx-translate/http-loader';
import { HttpClient, HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
import { HttpModule } from '@angular/http';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';

import { RootComponent } from './root.component';
import { AppComponent } from './app.component';
import { AppRoutingModule } from './app.routing';

import { InMemoryWebApiModule } from 'angular-in-memory-web-api';
import { InMemoryDataService } from '../db/in-memory-data.service';

import { AppInterceptor } from './_core/app.interceptor';
import { FooterComponent } from './_core/footer/footer.component';
import { HeaderComponent } from './_core/header/header.component';
import { DataService } from './_core/data.service';
import { DataResolver } from './_core/data.resolver';

import { environment } from '../environments/environment';
import { AppGuard } from './app.guard';

import { MessageService } from './message.service';
import { GatewayService } from './shared/gateway.service';
import { WindowRefService } from './window-ref.service';

/*
* Main module for the app that boostraps everything.
*/
@NgModule({
    imports: [
        BrowserModule,
        HttpClientModule,
        TranslateModule.forRoot({
          loader: {
            provide: TranslateLoader,
            useFactory: HttpLoaderFactory,
            deps: [HttpClient]
          }
        }),
        HttpModule,
        FormsModule,
        AppRoutingModule,
        BrowserAnimationsModule,
        InMemoryWebApiModule.forRoot(InMemoryDataService, { dataEncapsulation: false }) // Remove to use real HTTP calls
    ],
    declarations: [
        RootComponent,
        HeaderComponent,
        AppComponent,
        FooterComponent
    ],
    providers: [
        AppGuard,
        DataService,
        DataResolver,
        MessageService,
        GatewayService,

        WindowRefService,
        {
            provide: HTTP_INTERCEPTORS,
            useClass: AppInterceptor,
            multi: true,
        }
    ],
    bootstrap: [RootComponent]
})

export class AppModule { }

// required for AOT compilation
export function HttpLoaderFactory(http: HttpClient) {
    return new TranslateHttpLoader(http);
}

I've tried all the common solutions, including using the CopyWebpackPlugin to try to resolve the webpack bundling, adding the i18n directory to the assets list in angular-cli.json, and explicitly passing my path to TranslateHttpLoader like so:

return new TranslateHttpLoader(http, "./assets/i18n/", ".json");

None of these approaches have worked.

Is there something very basic I'm missing in my setup? I feel like I've just been looking at it too long at this point. :/

Most helpful comment

@ellenchristine in your angular-cli the prefix and assets should refer to the paths as shown below.

"assets": [
        "assets",
        "favicon.png"
      ],
 "prefix": "app"

Then refer it like this in your root module

export function createTranslateLoader(http: HttpClient) {
  return new TranslateHttpLoader(http, './assets/i18n/', '.json');
}

All 17 comments

Check your angular cli configuration, I'm pretty sure the mistake comes from here.

You can look in apps > prefix and add its value before ./assets/i18n/.

if you are using the cli, you may need to include it in the paths folder in angular-cli.json

@ellenchristine in your angular-cli the prefix and assets should refer to the paths as shown below.

"assets": [
        "assets",
        "favicon.png"
      ],
 "prefix": "app"

Then refer it like this in your root module

export function createTranslateLoader(http: HttpClient) {
  return new TranslateHttpLoader(http, './assets/i18n/', '.json');
}

I had the same problem, the InMemoryDataService intercepts your requests to the real server.
To fix this you can set passThruUnknownUrl: true like this:
InMemoryDataService, {dataEncapsulation: false, passThruUnknownUrl: true}

I also had this issue using webpack 4. It turned out that json files had to be copied to the dist folder along with the rest of the compilation, so I used copy-webpack-plugin for that. In my webpack config:

const CopyWebpackPlugin = require('copy-webpack-plugin');
...
  plugins: [
    new CopyWebpackPlugin([
      { from: helpers.root('src'), to: helpers.root('dist') }
    ]),
  ],

It solved the problem and json files are loaded correctly now. At least when using dev server...

I have the same Problem. With Angular Version 6.

But there isn't a angular-cli.json File. So I add the path in the angualr.json

"projects": { "navigatorWebClient": { "root": "", "sourceRoot": "src", "projectType": "application", "prefix": "gue", "schematics": { "@schematics/angular:component": { "styleext": "scss" } }, "architect": { "build": { "builder": "@angular-devkit/build-angular:browser", "options": { "outputPath": "dist/navigatorWebClient", "index": "src/index.html", "main": "src/main.ts", "polyfills": "src/polyfills.ts", "tsConfig": "src/tsconfig.app.json", "assets": [ "src/favicon.ico", "src/assets", "src/assets/i18n" ], "styles": [ "src/styles.scss" ], "scripts": [] },

But the Error isn't disappear

My ngx-translate-Version is

"@ngx-translate/core": "^10.0.2",
"@ngx-translate/http-loader": "^3.0.1",

best regards
McGurk

I have the same problem with the version of angular 6 and 7 if someone knows how to solve them?

I only have problems with the construction and deployment on the server

When used in my premises everything works correctly

You can use you own loader, this one works with SSR too:

import { translationFr } from 'assets/i18n/fr';
import { of, Observable } from 'rxjs';
import { TranslateLoader as NgxTranslateLoader } from '@ngx-translate/core';

const TRANSLATIONS = {
    fr: translationFr
};

export class TranslateLoader implements NgxTranslateLoader {

    public getTranslation(lang: string): Observable<any> {
        return of(TRANSLATIONS[lang]);
    }
}

export function translateFactory() {
    return new TranslateLoader();
}

import { HttpClientModule } from '@angular/common/http';
import { NgModule } from '@angular/core';
import { translateFactory } from '@shared/services/translate-loader.service';
import { TranslateLoader, TranslateModule as NgxTranslateModule, TranslateService } from '@ngx-translate/core';

@NgModule({
    imports: [
        HttpClientModule,
        NgxTranslateModule.forRoot({
            loader: {
                provide: TranslateLoader,
                useFactory: translateFactory
            }
        })
    ],
    exports: [ NgxTranslateModule ]
})

export class TranslateModule {
    constructor(translate: TranslateService, inputFileService: InputFileService) {
        translate.addLangs(['fr']);
        translate.setDefaultLang('fr');
    }
}

Why not use a typescript file instead of json? :)

Example: src > assets >i18n > fr.ts

export const translationFr = {
 // my translations
};

I had the same problem, the InMemoryDataService intercepts your requests to the real server.
To fix this you can set passThruUnknownUrl: true like this:
InMemoryDataService, {dataEncapsulation: false, passThruUnknownUrl: true}

Worked for me, if I disabled InMemoryDataService would work but not when enabled so the passThruUnknownUrl config property did the trick.

I had the same problem, the InMemoryDataService intercepts your requests to the real server.
To fix this you can set passThruUnknownUrl: true like this:
InMemoryDataService, {dataEncapsulation: false, passThruUnknownUrl: true}

It works

try this 2 option..

export const environment = {
production: true,
appRootPrefix: '/<>'
};

export function createTranslateLoader(http: HttpClient) {
return new TranslateHttpLoader(http, './assets/i18n/', '.json');
}

Worked for me too.
return new TranslateHttpLoader(http, "/BASEHREF/assests/i18n", ".json");

@pookdeveloper thanks, worked for me

I had the same problem, Is there any way to solve it now

Worked for me too.
return new TranslateHttpLoader(http, "/BASEHREF/assests/i18n", ".json");

@Aprajita-96 How did you solve it

At the moment, the only thing that worked for me is to change the .json extension of the files to .txt. Then put this in the
module (for local DEV I keep the json files, else I would have to copy each time if I would like to check translations):

export function httpTranslateLoader(http: HttpClient) {
  if (environment.production == true)
  {
    return new TranslateHttpLoader(http, "./assets/i18n/", ".txt");
  }
  else
  {
    return new TranslateHttpLoader(http, "./assets/i18n/", ".json");
  }
}

If I tried to enter the url of the json file in the browser, it didn't work, now if i try this with the txt file in the same folder it works. So the .json file are intercepted. I have a MSAL http interceptor which I cannot just remove.
Its not the best solution, but it works, if I can find a better way, I would love to. Now after each deploy to production, I need to copy these translation files to txt.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

alkemist picture alkemist  路  3Comments

guysan picture guysan  路  4Comments

bjornharvold picture bjornharvold  路  3Comments

apreg picture apreg  路  3Comments

louisdoe picture louisdoe  路  3Comments