Search code examples
angularserver-side-renderingangular-universalangular2-universal

angular 4 universal - different component / module for server and browser


So I have a simple wrapper for a jquery plugin, however obviously the wrapper bugs-out on universal because of a lack of browser global objects.

Like most jquery plugins, this plugin also

What I want to know if there's a simple way that we can have two different versions of a component/module, one for universal and one for non-universal.

Universal does have a separate starting 'app' module (which is used to load BrowserAnimationsModules vs NoopAnimationsModule) but that only works because these modules export services.


Solution

  • I can provide you with some suggestions that you can try out. I am also pretty new to angular-universal. This is a common issue among universal users.

    "... because of a lack of browser global objects"

    Yes! oftentimes, you see errors on universal like "document not found", "navigator not found", "window not found", etc.

    Solution for this?

    You could try using jsdom, which will eliminate such warnings by emulating enough of a subset of a web browser.

    anything else?

    You can run those code that err out, only on the client-side thereby eliminating any errors on your console. To do this, you can use a solution provided here by the universal team.

    Here is what they say :

    If you need to use them, consider limiting them to only your client and wrapping them situationally. You can use the Object injected using the PLATFORM_ID token to check whether the current platform is browser or server.

     import { PLATFORM_ID } from '@angular/core';
     import { isPlatformBrowser, isPlatformServer } from '@angular/common';
    
     constructor(@Inject(PLATFORM_ID) private platformId: Object) { ... }
    
     ngOnInit() {
       if (isPlatformBrowser(this.platformId)) {
          // Client only code.
          ...
       }
       if (isPlatformServer(this.platformId)) {
         // Server only code.
         ...
       }
     }  
    

    Now, let's say you have a problem where, you need to insert a 3rd party library for - let's say - a slider, which you do not want to be loaded on the server side, adding more bloat to initial load.

    In such scenarios, you can dynamically inject everything after the server side render. Here is an excellent answer that you can combine with the above snippet to meet this requirement.

    I hope, I have given you a rough idea of how to deal with your situation. If you have any queries, let me know.