Different views for Desktop and mobile Angular

Don't use canActivate or route guards, because they need to be used for authentication etc.

New way:

{
    path: 'your-path',
    loadChildren: () => {
      if(window.innerWidth > 768 ) {
        return import('./your-desktop.module').then(m => m.YourDesktopModule)
      } else {
        return import('./your-mobile.module').then(m => m.YourMobileModule)
      }
    }
}

As I said in the question comment section, route guards would be a good solution for this purpose.

The MobileGuard would look like this :

export class MobileGuard implements CanActivate {
    constructor(private _router: Router, private _mobileService: MobileService) {}

    canActivate(): boolean {
        const isMobile = this._mobileService.isMobile();
        if(!isMobile) {
            this._router.navigate(['/desktop']);
        }
        return isMobile;
    }
}

The same for the DesktopGuard.

The user trying to access any of the routes, would be redirected to the right one.

Here is a running example with this suggested solution.

And here is the stackblitz editable version.


I agree with @CarbonDry that using a logic in your RoutingModule is the best way. However I think using window size is a poor way to detect device type. Of course, it depends on the use case - if you simply need to show different UI for small screens, window.innerWidth will do. If you want separate functionality for mobiles, it might not be just enough.

There are various ways you could check for device type, for example you can use navigator.orientation === undefined to check if a device is desktop (because desktops do not support navigator.orientation.

Lastly, you could always use UserAgent detection. For that, refer to this thread https://stackoverflow.com/a/13819253/8775880

So in the end, your code might look like this

const isDesktop(): boolean => {
   return navigator.orientation === undefined;
}

{
    path: 'path',
    loadChildren: () => {
      if(isDesktop())
        return import('./desktop.module').then((m) => m.DesktopModule);
      return import('./mobile.module').then((m) => m.MobileModule);
    }
}

Edit Keep in mind, however, that loadChildren will run only once when the path is loaded for the first time. So again, you might want to consider simply checking the screen dimensions. Let's say that 768px works for portrait on phone, but what if I open the site in landscape mode? In some situations, even landscape mode requires mobile UI. But if you only check client width, you will get desktop version.