Detect if is mobile based on url (starting with "m." like facebook) that works with SSG
Answered
Transvaal lion posted this in #help-forum
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
34 Replies
if you want to have it on client side, you should better use:
window.location.hostname
which would like smth like this https://m.facebook.com => console.log(window.location.hostname) // m.facebook.com
@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
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
// DomainProvider using Context
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);
}
}, []);
@necm1 so my approach at this point
layout.tsx
typescript
return <html><body> <DomainProvider>{children}</DomainProvider> </body></html>
// DomainProvider using Context
typescript
const [isMobile, setIsMobile] = useState<boolean>(false);
useEffect(() => {
const hostname = window.location.hostname;
if (hostname.startsWith('m.')) {
setIsMobile(true);
}
}, []);
Transvaal lionOP
but won`t it render the desktop version on server (event if starting with m.) then rerender the mobile version on client?
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');
};
}, []);
@Transvaal lion but won`t it render the desktop version on server (event if starting with m.) then rerender the mobile version on client?
is there a specific reason to use SSG over SSR?
@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: