There are many topics and SO questions. but I don't find the best solution to detect mobile device.
I have two ponents. the first ponent is only for desktop, the second ponent is only mobiles.
{isMobile?
(<SecondComponent />)
:
(<FirstComponent />)
}
most solutions used getInitialProps
function. but the Nextjs says:
Remended: getStaticProps or getServerSideProps
.
link
There are many topics and SO questions. but I don't find the best solution to detect mobile device.
I have two ponents. the first ponent is only for desktop, the second ponent is only mobiles.
{isMobile?
(<SecondComponent />)
:
(<FirstComponent />)
}
most solutions used getInitialProps
function. but the Nextjs says:
Remended: getStaticProps or getServerSideProps
.
link
Share Improve this question edited Jun 14, 2021 at 19:05 isherwood 61.1k16 gold badges121 silver badges169 bronze badges asked Jun 14, 2021 at 18:57 S.M_EmamianS.M_Emamian 17.4k40 gold badges154 silver badges273 bronze badges 5- 1 Does this answer your question? What is the best way to detect a mobile device? – Samathingamajig Commented Jun 14, 2021 at 18:59
- @Samathingamajig No, because nextjs has a Sever-Side rendering. – S.M_Emamian Commented Jun 14, 2021 at 19:01
-
1
Look at the userAgent of the request instead of
window.navigator
– Samathingamajig Commented Jun 14, 2021 at 19:02 - @Samathingamajig Have u a Nextjs Developer? because Nextjs has different way with jquery library. – S.M_Emamian Commented Jun 14, 2021 at 19:04
- Yes I have worked with NextJS before, there were also vanilla JS answers on that post I linked. Here's another one stackoverflow./a/61519537/12101554 – Samathingamajig Commented Jun 14, 2021 at 19:06
4 Answers
Reset to default 3The simple way is to let the browser tell you with matchMedia:
let isMobile = window.matchMedia("(max-width: 600px)").matches;
You use something like this:
export const isMobileDevice = () => /iPhone|iPad|iPod|Android/i.test(navigator.userAgent);
I haven't tried this, but this post suggesest using req.device
. So you could probably do something like this
export async function getServerSideProps(context) {
return {
props: {
device: context.req.device,
},
}
}
Edit: You will need express-device
installed.
I get this solution, check the width of the user device, based on that you decide if they are on mobile or desktop. I'm using Nextjs12.
//PageLayout.js
import Head from "next/head"
import { Footer } from "./footer/Footer.js"
import dynamic from "next/dynamic.js"
import { useCheckUserWidth } from "../context/CheckUserWidth.js"
const NavBar_Mobile = dynamic(() => import("./navBar/mobile/NavBar_M.js").then((mod) => mod.NavBar_M), { ssr: false })
const NavBar_Desktop = dynamic(() => import("./navBar/desktop/NavBar_D.js").then((mod) => mod.NavBar_D), { ssr: false })
export const PageLayout = ({ children}) => {
const { isMobile } = useCheckUserWidth()
return (
<>
<Head>
<title>My webpage</title>
</Head>
{isMobile ? (
<>
<NavBar_Mobile />
</>
) : (
<>
<NavBar_Desktop />
</>
)}
<main>{children}</main>
<Footer />
</>
)
}
The ponents to use, desktop and mobile
//NavBar_D.js & NavBar_D.js
export const NavBar_D = () => {//Code nav bar for desktop here...}
export const NavBar_M = () => {//Code nav bar for mobile here...}
Context
//CheckUserWidth.js
import { createContext, useContext } from "react"
import { useWidthSize } from "../utils/useWidthSize"
const CheckUserWidth = createContext(null)
export const CheckUserWidth_Provider = ({ children }) => {
const { isMobile } = useWidthSize()
return (
<CheckUserWidth.Provider
value={{
isMobile
}}>
{children}
</CheckUserWidth.Provider>
)
}
export const useCheckUserWidth = () => {
return useContext(CheckUserWidth)
}
Wrap the app with the context provider
//_app.jsx
function MyApp({ Component, pageProps }) {
return (
<CheckUserWidth_Provider>
<PageLayout>
<Component {...pageProps} />
</PageLayout>
</CheckUserWidth_Provider>
)
}
Finally, the customHook to check the width of the user device
//useWidthSize.js
import { useEffect, useState } from "react"
export const useWidthSize = () => {
const [widthWindow, setWidthWindow] = useState(768)
const [isMobile, setIsMobile] = useState(true)
useEffect(() => {
const handleResize = () => {
const widthWindowInsideResize = window.innerWidth
if (widthWindowInsideResize <= widthWindow) {
setIsMobile(true)
} else {
setIsMobile(false)
}
}
window.addEventListener("resize", handleResize)
handleResize()
return () => {
window.removeEventListener("resize", handleResize)
}
}, [])
return { isMobile, widthWindow }
}
I hope this help.