Indagamos en el mundo online y así tenerte la respuesta a tu dilema, si continúas con preguntas puedes dejarnos la pregunta y contestaremos con mucho gusto.
Solución:
Creo que debería hacerlo utilizando getInitialProps en su página, ya que se ejecuta tanto en el servidor como en el cliente, y obteniendo el tipo de dispositivo detectando primero si está recibiendo la solicitud de la página web (por lo que todavía está en el servidor), o si está volviendo a renderizar (por lo que está en el cliente).
// index.js
IndexPage.getInitialProps = ( req ) =>
let userAgent;
if (req) // if you are on the server and you get a 'req' property from your context
userAgent = req.headers['user-agent'] // get the user-agent from the headers
else
userAgent = navigator.userAgent // if you are on the client you can access the navigator from the window object
Ahora puede usar una expresión regular para ver si el dispositivo es un dispositivo móvil o de escritorio.
// still in getInitialProps
let isMobile = Boolean(userAgent.match(
/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile|WPDesktop/i
))
return isMobile
Ahora puede acceder al accesorio isMobile que devolverá true o false
const IndexPage = ( isMobile ) =>
return (
isMobile ? (I am on mobile!
) : (I am on desktop!
)
)
Recibí esta respuesta de este artículo aquí.Espero que te haya sido útil.
ACTUALIZAR
Desde Next 9.5.0, getInitialProps
va a ser reemplazado por getStaticProps
y getServerSideProps
. Tiempo getStaticProps
es para buscar static datos, que se utilizarán para crear una página html en el momento de la compilación, getServerSideProps
genera la página dinámicamente en cada solicitud y recibe la context
objeto con el req
apoyo como getInitialProps
. La diferencia es que getServerSideProps
no va a saber navigator
, porque es solo del lado del servidor. El uso también es un poco diferente, ya que debe exportar una función asíncrona y no declarar un método en el componente. Funcionaría de esta manera:
const HomePage = ( deviceType ) =>
let componentToRender
if (deviceType === 'mobile')
componentToRender =
else
componentToRender =
return componentToRender
export async function getServerSideProps(context) BlackBerry
export default HomePage
Tenga en cuenta que desde getServerSideProps
y getStaticProps
son mutuamente excluyentes, tendrá que renunciar a las ventajas SSG otorgadas por getStaticProps
para conocer el tipo de dispositivo del usuario. Sugeriría no usar getServerSideProps para este propósito si solo necesita manejar un par de detalles de estilo. Si la estructura de la página es muy diferente según el tipo de dispositivo, quizás valga la pena.
ÚLTIMA ACTUALIZACIÓN:
Entonces, si no le importa hacerlo del lado del cliente, puede usar la importación dinámica como lo sugieren algunas personas a continuación. Esto será para casos de uso en los que use static generación de páginas.
Creé un componente que pasa todos los react-device-detect
exportaciones como accesorios (sería prudente filtrar solo las exportaciones necesarias porque entonces no se agita el árbol)
// Device/Device.tsx
import ReactNode from 'react'
import * as rdd from 'react-device-detect'
interface DeviceProps
children: (props: typeof rdd) => ReactNode
export default function Device(props: DeviceProps)
return props.children(rdd)
// Device/index.ts
import dynamic from 'next/dynamic'
const Device = dynamic(() => import('./Device'), ssr: false )
export default Device
y luego, cuando desee utilizar el componente, puede hacerlo
const Example = () =>
return (
( isMobile ) =>
if (isMobile) return My Mobile View
return My Desktop View
)
Personalmente, solo uso un gancho para hacer esto, aunque el método de accesorios inicial es mejor.
import useEffect from 'react'
const getMobileDetect = (userAgent: NavigatorID['userAgent']) => isWindows())
const isDesktop = () => Boolean(!isMobile() && !isSSR())
return
isMobile,
isDesktop,
isAndroid,
isIos,
isSSR,
const useMobileDetect = () =>
useEffect(() => , [])
const userAgent = typeof navigator === 'undefined' ? 'SSR' : navigator.userAgent
return getMobileDetect(userAgent)
export default useMobileDetect
Tuve el problema de que la animación de desplazamiento era molesta en los dispositivos móviles, así que hice un componente de animación de desplazamiento habilitado basado en el dispositivo;
import React, ReactNode from 'react'
import ScrollAnimation, ScrollAnimationProps from 'react-animate-on-scroll'
import useMobileDetect from 'src/utils/useMobileDetect'
interface DeviceScrollAnimation extends ScrollAnimationProps
device: 'mobile'
export default function DeviceScrollAnimation( device, animateIn, animateOut, initiallyVisible, ...props : DeviceScrollAnimation)
const currentDevice = useMobileDetect()
const flag = device === 'mobile' ? currentDevice.isMobile() : device === 'desktop' ? currentDevice.isDesktop() : true
return (
)
ACTUALIZAR:
así que después de seguir bajando por la madriguera del conejo, la mejor solución que se me ocurrió es usar react-device-detect en un useEffect, si inspecciona más a fondo la detección del dispositivo, notará que exporta las constantes que se establecen a través del ua-parser-js
lib
export const UA = new UAParser();
export const browser = UA.getBrowser();
export const cpu = UA.getCPU();
export const device = UA.getDevice();
export const engine = UA.getEngine();
export const os = UA.getOS();
export const ua = UA.getUA();
export const setUA = (uaStr) => UA.setUA(uaStr);
Esto da como resultado que el dispositivo inicial sea el servidor que causa false detección.
Bifurqué el repositorio y creé y agregué un selector ssr que requiere que pases un agente de usuario. que se podría hacer usando los accesorios iniciales
ACTUALIZAR:
Debido a que los Ipads no brindan un agente de usuario correcto o bastante bien definido, vea este problema, decidí crear un gancho para detectar mejor el dispositivo
import useEffect, useState from 'react'
function isTouchDevice() (window?.DocumentTouch && document instanceof DocumentTouch)) return true
const query = ['(', prefixes.join('touch-enabled),('), 'heartz', ')'].join('') // include the 'heartz' - https://git.io/vznFH
return mq(query)
export default function useIsTouchDevice() {
const [isTouch, setIsTouch] = useState(false)
useEffect(() => , [])
return isTouch
Debido a que necesito el paquete cada vez que llamo a ese gancho, la información de UA se actualiza, también corrige las advertencias de SSR fuera de sincronización.
Nos puedes asentar nuestra labor ejecutando un comentario y dejando una valoración te damos las gracias.