Search code examples
javascriptreactjswebpackpreact

Which is the optimal way of implementing separate website for desktop and mobile in preact/react


I am working on a project using preact and nginx. Now, I am in a situation where we need the different UI and in few cases the flow is different for mobile devices compared to desktop. I explored some ways to implement this but still confused and not sure which is the optimal way to implement.

1) Using different url to redirect for mobile-devices(https://m.example.com) using nginx. MDN also suggests, When to use different url for diffrent devices

server {
    ...
    server_name www.example.com;
    ...
    proxy_set_header X-Forwarded-Host $host;
    proxy_set_header X-Forwarded-Server $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

    location / {
        if ($http_user_agent ~* ...) {
            rewrite ^ /m$request_uri last;
        }
        proxy_pass http://localhost:8080;
    }
    location /m {
        proxy_pass http://localhost:8080;
    }
}

Cons: This will required to create separate repository for mobile-devices, results in maintaining two projects.

Is there a way to handle this without creating separate projects?

2) Use same url for all devices but create separate components from root components using packages like mobile-device-detect to detect user-agent and conditionally call components.

import { isMobile } from 'mobile-device-detect'
export default class App extends Component {
   render(props) {
      return (
         {!!isMobile ? <MobileComponent /> : <DesktopComponent />}
      )
   }
}

Cons: This method will increase the size of bundle, which might be very costly.

3) The solution to the above point cons could be code-splitting and lazy loading. But how is it possible to lazy load based on user-agent/ user device?


Solution

  • 1) You can create 2 apps from same codebase. Run your bundler twice with different entry points for mobile & desktop sites. You can reuse your hooks, utility functions, state management, etc.

    2,3) Lazy load <MobileComponent /> and <DesktopComponent /> with (P)React.lazy and you are good to go. (Assuming you don't need server side rendering).