I’m trying to create a layout in Next.js where the component rendered depends on the device (mobile or desktop). I want to prevent the desktop layout’s source code from being downloaded to the browser if the user is on a mobile device. Here’s what I have:
"use server";
import React, {ReactNode, ComponentType} from "react";
import {parseUserAgent} from "@repo/helpers";
import dynamic from "next/dynamic";
import {headers} from "next/headers";
interface Props {
CommonWrapper?: ComponentType<{children: ReactNode}>;
MobileComponent: () => Promise<{default: React.ComponentType<any>}>;
DesktopComponent: () => Promise<{default: React.ComponentType<any>}>;
}
const withResponsiveLayout = async ({
CommonWrapper,
MobileComponent,
DesktopComponent,
}: Props) => {
const header = new Headers(headers());
const parsedUserAgent = parseUserAgent(header);
let isMobile = parsedUserAgent?.device.is("mobile");
const Wrapper = CommonWrapper ?? React.Fragment;
const Component = isMobile
? dynamic(MobileComponent)
: dynamic(DesktopComponent);
return (
<Wrapper>
<Component />
</Wrapper>
);
};
export default withResponsiveLayout;
// example
'use server'
async function Page() {
const data = await getSomeData();
return await withResponsiveLayout({
CommonWrapper: ({children}: PropsWithChildren) => (
<MandatoryAuthWrapper>
<CommonProvier initialData={data}>{children}</CommonProvier>
</MandatoryAuthWrapper>
),
DesktopComponent: () => import("./Main"),
MobileComponent: () => import("./MobMain"),
});
}
I’m trying to render either a mobile or desktop layout based on the user-agent, and I want to ensure that the desktop layout never gets downloaded by the browser if the user is on a mobile device. I don’t want to make the layout responsive but rather load an entirely different layout based on the device.
Am I doing something wrong in my approach? How can I ensure the desktop component is excluded from the client-side bundle entirely when the user is on a mobile device?