Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug(SSR): npm run prerender fails with HttpErrorResponse #703

Open
1 task done
limes opened this issue Sep 12, 2023 · 6 comments
Open
1 task done

Bug(SSR): npm run prerender fails with HttpErrorResponse #703

limes opened this issue Sep 12, 2023 · 6 comments

Comments

@limes
Copy link

limes commented Sep 12, 2023

Is there an existing issue for this?

  • I have searched the existing issues

Which Transloco package(s) are the source of the bug?

Transloco

Is this a regression?

No

Current behavior

  1. ng new
  2. ng add @nguniversal/express-engine
  3. ng add @ngneat/transloco
  4. Add {{ 'hello' | transloco }} to app.component.html
  5. Add { "hello": "world" } to assets/i18n/en.json
  6. ng build && ng run {app-name}:server <- works fine
  7. npm run prerender <- fails with error below:
Prerendering 1 route(s) to (...)browser...Error while trying to load "en" HttpErrorResponse {
    headers: HttpHeaders {
      normalizedNames: Map(0) {},
      lazyUpdate: null,
      headers: Map(0) {}
    },
    status: 0,
    statusText: 'Unknown Error',
    url: 'http://localhost:4200/assets/i18n/en.json',
    ok: false,
    name: 'HttpErrorResponse',
    message: 'Http failure response for http://localhost:4200/assets/i18n/en.json: 0 Unknown Error',
    error: ProgressEvent2 {
      type: 'error',
      target: XMLHttpRequest2 {
        onloadstart: null,
        onprogress: null,
        onabort: null,
        onerror: null,
        onload: null,
        ontimeout: null,
        onloadend: null,
        _listeners: [Object],
        onreadystatechange: null,
        _anonymous: undefined,
        readyState: 4,
        response: null,
        responseText: '',
        responseType: 'text',
        responseURL: '',
        status: 0,
        statusText: '',
        timeout: 0,
        upload: [XMLHttpRequestUpload],
        _method: 'GET',
        _url: [Url],
        _sync: false,
        _headers: [Object],
        _loweredHeaders: [Object],
        _mimeOverride: null,
        _request: null,
        _response: null,
        _responseParts: null,
        _responseHeaders: null,
        _aborting: null,
        _error: null,
        _loadedBytes: 0,
        _totalBytes: 0,
        _lengthComputable: false
      },
      currentTarget: XMLHttpRequest2 {
        onloadstart: null,
        onprogress: null,
        onabort: null,
        onerror: null,
        onload: null,
        ontimeout: null,
        onloadend: null,
        _listeners: [Object],
        onreadystatechange: null,
        _anonymous: undefined,
        readyState: 4,
        response: null,
        responseText: '',
        responseType: 'text',
        responseURL: '',
        status: 0,
        statusText: '',
        timeout: 0,
        upload: [XMLHttpRequestUpload],
        _method: 'GET',
        _url: [Url],
        _sync: false,
        _headers: [Object],
        _loweredHeaders: [Object],
        _mimeOverride: null,
        _request: null,
        _response: null,
        _responseParts: null,
        _responseHeaders: null,
        _aborting: null,
        _error: null,
        _loadedBytes: 0,
        _totalBytes: 0,
        _lengthComputable: false
      },
      lengthComputable: false,
      loaded: 0,
      total: 0
    }
  }
  ERROR Error: Unable to load translation and all the fallback languages

Expected behavior

Prerender process should work the same way as ng build && ng run {app-name}:server

Please provide a link to a minimal reproduction of the bug, if you won't provide a link the issue won't be handled.

See current behavior (1-3)

Transloco Config

provideTransloco({
        config: {
          availableLangs: ['en', 'es'],
          defaultLang: 'en',
          // Remove this option if your application doesn't support changing language in runtime.
          reRenderOnLangChange: true,
          // prodMode: !isDevMode(),
        },
        loader: TranslocoHttpLoader
      }),

Please provide the environment you discovered this bug in

Transloco: 5.0.7
Angular: 16
Node: 18
Package Manager: yarn v1
OS: macOS (13.5.2)

Browser

SSR

Additional context

No response

I would like to make a pull request for this bug

No

@alcaidio
Copy link

alcaidio commented Oct 6, 2023

Somebody know how to do prerendering with transloco ?

@NLueg
Copy link

NLueg commented Nov 15, 2023

Heyo, I solved this by providing a special TranslocoLoader only for the server. I already use this in production with success.
This is the AppServerModule I updated to provide the new loader

@NgModule({
  imports: [AppModule, ServerModule, IonicServerModule],
  providers: [
    { provide: TRANSLOCO_LOADER, useClass: TranslocoServerHttpLoaderService },
  ],
  bootstrap: [AppComponent],
})
export class AppServerModule {}

The loader itself don't tries to get the JSON files by using a HTTP call and just uses the file system:

@Injectable({
  providedIn: 'root',
})
export class TranslocoServerHttpLoaderService implements TranslocoLoader {
  getTranslation(lang: string): Observable<Translation> {
    const assetsFolder = join(
      process.cwd(),
      'dist',
      'app',
      'browser',
      'assets',
      'i18n',
    );
    return of(
      JSON.parse(fs.readFileSync(`${assetsFolder}/${lang}.json`, 'utf8')),
    );
  }
}

With this solution I managed it to prerender the files for different languages.

@asapha
Copy link

asapha commented Jan 31, 2024

Had a similar issue in an existing app, the new pre-rendering done in ng build failed.
I fixed it by following the docs' recommendation.

i.e changing

return this.http.get<Translation>(`${environment["baseUrl"]}/assets/i18n/${lang}.json`);

to

return this.http.get<Translation>(`/assets/i18n/${lang}.json`);

@phatyh
Copy link

phatyh commented Feb 13, 2024

Heyo, I solved this by providing a special TranslocoLoader only for the server. I already use this in production with success. This is the AppServerModule I updated to provide the new loader

@NgModule({
  imports: [AppModule, ServerModule, IonicServerModule],
  providers: [
    { provide: TRANSLOCO_LOADER, useClass: TranslocoServerHttpLoaderService },
  ],
  bootstrap: [AppComponent],
})
export class AppServerModule {}

The loader itself don't tries to get the JSON files by using a HTTP call and just uses the file system:

@Injectable({
  providedIn: 'root',
})
export class TranslocoServerHttpLoaderService implements TranslocoLoader {
  getTranslation(lang: string): Observable<Translation> {
    const assetsFolder = join(
      process.cwd(),
      'dist',
      'app',
      'browser',
      'assets',
      'i18n',
    );
    return of(
      JSON.parse(fs.readFileSync(`${assetsFolder}/${lang}.json`, 'utf8')),
    );
  }
}

With this solution I managed it to prerender the files for different languages.

thanks. my project angular v17 with ssr without standalone. solved my problem

@mackelito
Copy link

No updates on this issue?

@shaharkazaz
Copy link
Collaborator

@limes @mackelito Did you try the solution @NLueg suggested?
Feels like something worth mentioning in the docs if someone wants to open a PR and add it 🙂

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants