2

There are many topics and SO questions. but I don't find the best solution to detect mobile device.

I have two components. the first component is only for desktop, the second component is only mobiles.

{isMobile? 
(<SecondComponent />) 
: 
(<FirstComponent />)
}

most solutions used getInitialProps function. but the Nextjs says:

Recommended: getStaticProps or getServerSideProps.

link

isherwood
  • 58,414
  • 16
  • 114
  • 157
S.M_Emamian
  • 17,005
  • 37
  • 135
  • 254

4 Answers4

1

You use something like this:

export const isMobileDevice = () => /iPhone|iPad|iPod|Android/i.test(navigator.userAgent);

Abhishek Sharma
  • 2,485
  • 1
  • 21
  • 35
1

The simple way is to let the browser tell you with matchMedia:

let isMobile = window.matchMedia("(max-width: 600px)").matches;
samuei
  • 1,949
  • 1
  • 10
  • 26
0

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.

Baruch
  • 2,381
  • 1
  • 17
  • 29
  • 1
    You forgot to mention that you need the `express-device` middleware. Also, can express middleware work with NextJS? – Samathingamajig Jun 14 '21 at 19:11
  • @Samathingamajig sorry I didn't see the second part of your comment. Yea, you can have a custom server with express – Baruch Jun 14 '21 at 19:27
0

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 components 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.