Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Not Working with Next.js 13 / React 18.2 #196

Open
travis7777 opened this issue Nov 3, 2022 · 9 comments
Open

Not Working with Next.js 13 / React 18.2 #196

travis7777 opened this issue Nov 3, 2022 · 9 comments
Assignees

Comments

@travis7777
Copy link

  1. Was working prior to Next.js 13, now getting the following error on mobile: Unhandled Runtime Error
    Error: Text content does not match server-rendered HTML.
    See more info here: https://nextjs.org/docs/messages/react-hydration-error
  2. Install nextjs 13, reload page that has mobile/desktop logic
  3. Device user-agent - All Mobile seems
  4. Device/Browser type/name - Chrome
  5. Code:
    import {BrowserView, MobileView, isMobile} from 'react-device-detect'

const Footer = () => {

return (            
    <>
    <MobileView>              
      <>  
        Test        
      </>
    </MobileView>         
    <BrowserView>
      <>
        Test3  
      </>
    </BrowserView>  
    </>
);

}

export default Footer;

@chris-at-lemon
Copy link

chris-at-lemon commented Nov 17, 2022

I second this. As a workaround I wrap the sniffer in useEffect to trigger it after component has loaded:

  const [device, setDevice] = useState<string>();
  useEffect(() => {
    if (isIOS) {
      setDevice("ios");
    }
    if (isAndroid) {
      setDevice("android");
    }
  });

Then use as such:

{device === "android" && <>something</>}

In case it helps anyone out of a squeeze until there's a fix.

Cheers

Chris

@drbarazi
Copy link

hope this will help, i put on app/layout.tsx

"use client"
import '../styles/globals.css'
import { isMobile } from 'react-device-detect';
import { useEffect, useState } from 'react';

export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
const [mobile, setMobile] = useState(false)
const [isSSR, setIsSSR] = useState(true);

useEffect(() => {
    setIsSSR(false);
    setMobile(isMobile)
}, []);

if (isSSR)
    return (
        <html>
            <head />
            <body>
               Loading ....
            </body>
        </html>
    );

return (
    <html>
        <head />
        <body>
            {mobile ?
                <div>
                    <h1>This is rendered only on mobile</h1>
                    {children}
                </div>
                :
                <div>
                        <h1>This is rendered only in browser</h1>
                        {children}
                </div>
            }
        </body>
    </html>
)

}

@duskload duskload self-assigned this Feb 8, 2023
@jinojacob15
Copy link

@drbarazi u cannot make root layout a client component .

The statement form next js beta docs

DeepinScreenshot_select-area_20230306125945

@theDanielJLewis
Copy link

Aside from useEffect(), any better workarounds or updates about Next.js app router support?

@jamesryan-dev
Copy link

+1 following

@anoop0567
Copy link

@theDanielJLewis @jamesryan-dev found any workaround for this?

@theDanielJLewis
Copy link

@anoop0567, no. I'm forced into useEffect() with state within a client component.

Like this:

  const [device, setDevice] = useState<string>();

  useEffect(() => {
    if (isIOS) {
      setDevice("ios");
    }
    if (isMacOs) {
      setDevice("macos");
    }
    if (isAndroid) {
      setDevice("android");
    }
    if (isWindows) {
      setDevice("windows");
    }
  }, []);

return <>{device === "windows" && (<WindowsStuff />)}</>;

@gersooonn
Copy link

@anoop0567, não. Sou forçado a entrar useEffect()no estado de um componente cliente.

Assim:

  const [device, setDevice] = useState<string>();

  useEffect(() => {
    if (isIOS) {
      setDevice("ios");
    }
    if (isMacOs) {
      setDevice("macos");
    }
    if (isAndroid) {
      setDevice("android");
    }
    if (isWindows) {
      setDevice("windows");
    }
  }, []);

return <>{device === "windows" && (<WindowsStuff />)}</>;

I can't get mine to work even if I copy this code I send

@jamesryan-dev
Copy link

@anoop0567 i had to make my components client components and useState to handle any react-device-detect work

I never found a way to differentiate between tablets ( iPad ) and ios mobile devices which was a shame

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

9 participants