Saltar al contenido

¿Cómo detectar el dispositivo en la aplicación React SSR con Next.js?

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.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *