Next.js Discord

Discord Forum

Detect if is mobile based on url (starting with "m." like facebook) that works with SSG

Answered
Transvaal lion posted this in #help-forum
Open in Discord
Transvaal lionOP
import { useMediaQuery } from '@mantine/hooks';
import {
    useMantineTheme,
} from '@mantine/core';

export function useIsMobile() {
    const theme = useMantineTheme();

    const isMobile = useMediaQuery(`(max-width: ${theme.breakpoints.sm})`, url.startsWith("m."));

    return isMobile;
}


Is there anyway to do that on nextJs that works both on client and server (SSG?)

useMediaQuery returns the second parameter (default) if on server.
Answered by necm1
guess it would be less pain to use SSR, simple nginx proxy + cloudflare infront of the nginx proxy
View full answer

34 Replies

@necm1 what does url returns?
Transvaal lionOP
What if i want to static generate a mobile version of website? (when it starts with m.)
like loading different components (mobile components) on server level if the subdomain contains m?
but using SSG instead of SSR
so
just making things clear; next build provides SSG
isn't it
Transvaal lionOP
yes, i need two builds
one for xxx and one for m.xxx
maybe the best way is using environment variables?
but at the end; both are runned through next start
isn't it
you could deploy a version with the environment variables
but you could maybe use headers from next/headers
my bad headers is accessible in SSR
@necm1 my bad `headers` is accessible in SSR
Transvaal lionOP
But i don`t want ssr and instead SSG
so my approach at this point

layout.tsx
return <html><body> <DomainProvider>{children}</DomainProvider> </body></html>


// DomainProvider using Context
const [isMobile, setIsMobile] = useState<boolean>(false);

useEffect(() => {
  const hostname = window.location.hostname;

  if (hostname.startsWith('m.')) {
    setIsMobile(true);
  }
}, []);
so you could go into your header.tsx component and use smth like this

const domainContext = useContext(DomainContext); // exported from your DomainProvider

domainContext.isMobile //has to be defined in your context
I mean you could extend this logic with smth like
useEffect(() => {
  const hostname = window.location.hostname;

  if (!hostname.startsWith('m.')) {
     return;
  }

  const body = document.body.classList;

  if (body.contains('mobile')) {
    return;
  }

  body.add('mobile');

  return () => {
    body.remove('mobile');
  };
}, []);
@necm1 is there a specific reason to use SSG over SSR?
Transvaal lionOP
I`m using cloudflare pages to host (it supports only SSG, but even if has minimal support for SSG it costs money per click unlike ssg)
there is no way to get SSG detect mobile except for the client
due to the build bundle which SSG uses
only way could be only using the window.location.hostname
or create 2 projects / builds
@necm1 due to the build bundle which SSG uses
Transvaal lionOP
Yes, but the thing is. I`m deploying two websites, it is building two times. Probably the only way is using environment variables
then I guess go for the environment variables, so you can directly change them in cloudflare for you special needs
at the end; the result would be somehow the same (except for the useEffect approach which would load desktop and switch to mobile)
guess it would be less pain to use SSR, simple nginx proxy + cloudflare infront of the nginx proxy
Answer
Original message was deleted
@Transvaal lion could be awesome when you mark any answers from me as described here: