question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

SSR - Template loader still visible when serving the view

See original GitHub issue

I’m submitting a…

[ ] Regression (a behavior that used to work and stopped working in a new release)
[x] Bug report  
[ ] Performance issue
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request
[ ] Other... Please describe:

Current behavior

When serving a page with a Node server, the result contains the template loaders instead of the translations.

Expected behavior

When serving a page with a Node server, the result should contains the translations instead of the template loaders.

Minimal reproduction of the problem with instructions

Creating a repository with SSR seems very complicated to me nevertheless I am willing to give you as much information as possible to find out where is the problem.

What is the motivation / use case for changing the behavior?

I was using ngx-translate and despite the documentation saying say the SSR support is not available, the SSR was operating as expected with the translations being served.
The only difference was that the translations were already set on build time instead of fetched from a JSON file but only on the server-side.

I migrated from ngx-translate to transloco to extend the possibilities due to the nice features that transloco was able to bring me.
Now, the last piece of my road to transloco is to have the translation working on the server-side for SEO purpose.

Environment


Angular version: 8.2.14
@ngneat/transloco: 2.9.0
@ngneat/transloco-messageformat: 1.1.3
@ngneat/transloco-persist-lang: 1.0.1
@ngneat/transloco-persist-translations: 1.0.0
@nguniversal/express-engine: 8.1.1
@nguniversal/module-map-ngfactory-loader: 8.1.1

Browser:
- [x] Chrome (desktop) version XX
- [ ] Chrome (Android) version XX
- [ ] Chrome (iOS) version XX
- [ ] Firefox version XX
- [ ] Safari (desktop) version XX
- [ ] Safari (iOS) version XX
- [ ] IE version XX
- [ ] Edge version XX
 
For Tooling issues:
- Node version: 12.3.1
- Platform: Windows

More information

Rendering result

<ng-component class="ng-star-inserted">
    <div class="transloco-loader-template">
        <span>Loading...</span>
    </div>
</ng-component>

Transloco loader

  public getTranslation(lang: string): Observable<Translation> {
    const isProduction: boolean = this.ptlEnvironmentService.isProduction();
    const externalAssetsUrl: string = this.ptlEnvironmentService.getExternalAssetsUrl();
    let i18nUrl: string;

    // The logs on the Node server are pointing on a valid location here
    if (isProduction) {
      i18nUrl = `${externalAssetsUrl}/extassets/customer-portal/i18n/${lang}.json?v=${cacheBusting[ lang ]}`;
    } else {
      i18nUrl = `./assets/i18n/${lang}.json?v=${cacheBusting[ lang ]}`;
    }

    return this.httpClient.get<Translation>(i18nUrl);
  }

Transloco app module config

    TranslocoModule,
    TranslocoPersistTranslationsModule.init({
      loader: TranslocoHttpLoader,
      storage: {
        provide: PERSIST_TRANSLATIONS_STORAGE,
        useValue: i18nLocalForage
      },
      storageKey: 'i18n',
      ttl: ONE_HOUR
    }),
    TranslocoPersistLangModule.init({
      storage: {
        provide: TRANSLOCO_PERSIST_LANG_STORAGE,
        useValue: langLocalForage
      }
    }),
    TranslocoMessageFormatModule.init({
      locales: 'fr-FR'
    }),

Transloco config provider

export const TRANSLOCO_CONFIG_PROVIDER: ValueProvider = {
  provide: TRANSLOCO_CONFIG,
  useValue: <TranslocoConfig>{
    availableLangs: [
      'fr',
      'en'
    ],
    defaultLang: 'fr',
    failedRetries: 3,
    fallbackLang: 'en',
    flatten: {
      aot: ENVIRONMENT.production
    },
    missingHandler: {
      allowEmpty: ENVIRONMENT.production,
      logMissingKey: !ENVIRONMENT.production,
      useFallbackTranslation: false
    },
    prodMode: ENVIRONMENT.production,
    reRenderOnLangChange: true
  }
};

Again, I am not sure at all that transloco is the problem here but I have no idea in this case on how to fix my problem so any help would be very much appreciable.

Thanks !

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:10

github_iconTop GitHub Comments

5reactions
itayodcommented, Dec 8, 2019

Use the PLATFORM_ID in factory to get the localForage only on the browser:

export function getStorage(platformId: PLATFORM_ID) {
  return isPlatformBrowser(platformId) ? localForage : dummyStorage
}
@NgModule({
imports: [
    TranslocoPersistLangModule.init({
      storage: {
        provide: TRANSLOCO_PERSIST_LANG_STORAGE,
        deps: [PLATFORM_ID],
        useFactory: localStorage
      }
    }),
...
1reaction
C0ZENcommented, Dec 5, 2019

Hello @itayod. I have news for you.

You can check below what I changed for the tests.

app.module.ts

export function createStorageMock(): any {
  return new (class Storage implements MaybeAsyncStorage {
    private _storage = {};

    public getItem(key: string): any {
      return this._storage[ key ];
    }

    public setItem(key: string, value: any): void {
      this._storage[ key ] = value + '';
    }

    public removeItem(key: string): void {
      delete this._storage[ key ];
    }
  })();
}

TranslocoPersistTranslationsModule.init({
      loader: TranslocoHttpLoader,
      storage: {
        provide: PERSIST_TRANSLATIONS_STORAGE,
        useValue: createStorageMock()
      },
      storageKey: 'i18n',
      ttl: ONE_HOUR
    }),

The result is fine. The problem is fixed.

Obviously, this is a problem between localForage and transloco.
I hope you will be able to find a way to fix this.

However I do not think I can do more to help here (no PR) but let me know if you need more tests from me.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Why does the client fetched data appear in view source for ...
I've worked on VUE SSR projects and when the client navigation starts, if you inspect the page source, you don't find the data...
Read more >
Client-side vs. Server-side vs. Pre-rendering for Web Apps
There's no question that user experience is impacted by perceived load times. With today's heavier front ends, client-side rendering doesn't feel very fast....
Read more >
Server-Side Rendering (SSR) - Vue.js
Server-rendered markup doesn't need to wait until all JavaScript has been downloaded and executed to be displayed, so your user will see a...
Read more >
How to Enable Server-Side Rendering for a React App
First, use npx to start up a new React app using the latest version of Create React App. Let's call the app, react-ssr-example...
Read more >
Server-side rendering (SSR) with Angular Universal
The sample web server for this guide is based on the popular Express framework. NOTE: Any web server technology can serve a Universal...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found