When developing web applications with JSF and PrimeFaces most target users are still using PC or laptops as they will use the application mainly during work hours. Mobile devices like smartphones or tablets are supposed to work without code modifications, but most of the times there are no optimized layouts for those devices.
PrimeFaces offers both mobile and web components to optimize the look & feel for mobile and (standard) web interfaces. I created a small project to show the structure and workflow for detecting a device and showing an optimized view without changing the java code of the model or controller layer.
The following image shows the project structure of the sample project.

As you can see the views for web and mobile devices are separated in two folders. The web folder contains the (standard) web views used for PC and notebooks, the mobile folder contains the optimized views for mobile devices. When entering the base view (switch.xhtml), the application should find out the current device by looking at the “User-Agent” header of the current request.
@ApplicationScoped
@Named
public class MobileSwitch {
private RenderMode findBrowserRenderMode() {
FacesContext facesContext = FacesContext.getCurrentInstance();
ExternalContext externalContext = facesContext.getExternalContext();
String userAgent = externalContext.getRequestHeaderMap().get("User-Agent");
return userAgent.toLowerCase().contains("mobile") ? RenderMode.MOBILE : RenderMode.WEB;
}
public String findRenderMode() {
return findBrowserRenderMode().name();
}
public void switchTo(String renderMode) throws IOException {
FacesContext facesContext = FacesContext.getCurrentInstance();
String viewId = facesContext.getViewRoot().getViewId();
RenderMode nextRenderMode = RenderMode.valueOf(renderMode);
ExternalContext externalContext = facesContext.getExternalContext();
String context = externalContext.getRequestContextPath();
viewId = viewId.substring(viewId.lastIndexOf("/") + 1);
externalContext.redirect(String.format("%s/%s/%s", context, nextRenderMode.name().toLowerCase(), viewId));
}
}
The navigation rule configured in the faces-config.xml file will check the outcome of the MobileSwitch class and redirect to the best fitting view for mobile and web devices.
org.primefaces.mobile.application.MobileNavigationHandler /switch.xhtml MOBILE /mobile/index.xhtml WEB /web/index.xhtml
Both views for web and mobile devices have a button to switch to the other render mode. This is handled by the switchTo(String renderMode) method of the MobileSwitch class. It does a simple redirect to the chosen view.


The PrimeFaces view for mobile devices needs to include the namespace of the PrimeFaces mobile components xmlns:pm=”http://primefaces.org/mobile” and it must be rendered by its own render kit by adding the correct renderkit id:
JSF Mobile Application
VDL (the PrimeFaces tag javadoc): http://www.primefaces.org/docs/vdl/6.0/mobile/
Sample Project (zip file containing the java / maven project): jsfmobile

I couldn’t find on the web no solution so convenient, practical and elegant. Thanks for sharing your work.