Render different components based on screen size in Next.js #14810
Replies: 19 comments 40 replies
-
I'm in the exact same situation, and would love to see a response posted here. I need one of my Next.js components to know the innerWidth of the window object on the initial render. |
Beta Was this translation helpful? Give feedback.
-
Hi, you can use a media query hook
|
Beta Was this translation helpful? Give feedback.
-
amazing will try this out. thanks for the help
- Jon Rivera
jonrrivera.com
… On Sep 3, 2020, at 12:06 PM, Junior Garcia ***@***.***> wrote:
Hi, you can use a media query hook
`import { useState, useCallback, useEffect } from 'react';
const useMediaQuery = (width) => {
const [targetReached, setTargetReached] = useState(false);
const updateTarget = useCallback((e) => {
if (e.matches) {
setTargetReached(true);
} else {
setTargetReached(false);
}
}, []);
useEffect(() => {
const media = window.matchMedia((max-width: ${width}px));
media.addListener(updateTarget);
// Check on mount (callback is not called until a change occurs)
if (media.matches) {
setTargetReached(true);
}
return () => media.removeListener(updateTarget);
}, []);
return targetReached;
};
const Navbar = () => {
const isBreakpoint = useMediaQuery(768)
return (
{ isBreakpoint ? (
) : (
)
)}
export default Navbar;
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub, or unsubscribe.
|
Beta Was this translation helpful? Give feedback.
-
So does this code runs serverside and therefore preserve static or serverside rendered pages? I thought using useEffect would mean you opt out of serverside rendering? |
Beta Was this translation helpful? Give feedback.
-
The proposed solution is very flawed since it causes mismatches between server-render and client-render. I'd love to see an official solution for this. |
Beta Was this translation helpful? Give feedback.
-
I think the only way to do this would be to get this data from nextjs app context, more specifically the |
Beta Was this translation helpful? Give feedback.
-
it could be OK on server component for SSR import { headers } from 'next/headers' export const getDeviceType = () => { return userAgent!.match( |
Beta Was this translation helpful? Give feedback.
-
Use Sec-CH-UA-Mobile client hint for server-side rendering for mobile and desktop, and fallback to user-agent for Safari. There is also a |
Beta Was this translation helpful? Give feedback.
-
Can we cache rendered result separately for desktop and mobile if we use |
Beta Was this translation helpful? Give feedback.
-
Hi guys, I'm trying to achieve this in Next 14 app router in middleware.ts. I use userAgent to retrieve the device information but it always undefined, Is this normal ?
Any help ? |
Beta Was this translation helpful? Give feedback.
-
It's work for me on next.js 14. ------------------- Custom Hook for Getting MediaQuery , Device Type or Width for Next.js 14. ------------------------------ const useMediaQuery = (query) => {
}; export default useMediaQuery; ---------------------------- Use cases on component --------------------------- const isMobile = useMediaQuery('(max-width: 768px)'); return ( {isMobile && This content is displayed on mobile devices. }); |
Beta Was this translation helpful? Give feedback.
-
This is what I use: I define a custom hook: src/lib/hooks/use-media-query.ts:
Then I create a client component to deal with the browser, but most importantly, to be able to render RSC components: src/components/composables/media-rendering.tsx:
So, let's suppose I have a
Just FYI: this would be the NavMenu.tsx:
|
Beta Was this translation helpful? Give feedback.
-
Sorry for the delay in my answer. I usually don't need so much stuff in order to achieve this. Performance for me is key. And yes, I pass a React server Component as the children of the |
Beta Was this translation helpful? Give feedback.
-
If by "flickering" you mean that you experience shift arounds that affect CLS, that's out of the scope of the way you use to render something different from another thing. Either way you use it's going to cause "flickering" if the |
Beta Was this translation helpful? Give feedback.
-
For the record: You can go just with one In this particular case I had to use this Normally you render something or not at all based on the device width, so you only need a prop. |
Beta Was this translation helpful? Give feedback.
-
Just chiming in here would also love to see a real Next.js way of doing this. Using matchMedia isn't a good solution as it causes CLS/FOUC if the elements are below the fold it's fine but otherwise it's bad. |
Beta Was this translation helpful? Give feedback.
-
Here's one that persist its state using cookies to avoid the small flickering when reloading. |
Beta Was this translation helpful? Give feedback.
-
I've solved my "version" of this issue purely in CSS. I always render both the mobile and the desktop version of the component, but I apply a default This means I avoid the need for a screen size hook entirely and I also don't get the loading "stretch". This also allows me to serve my toolbar as an RSC, since it doesn't need any client hooks. |
Beta Was this translation helpful? Give feedback.
-
I'm trying to render render a component differently based on if the screen width < 768p.
If it is less than 768p, then load the hamburger menu. If not, load the entire menu.
Here's the code I use. The issue is, when the page first loads, I cannot observe the changes. But when I make the browser screen small and then increase it to it's original size; the effects take place.
I think it's because React is being rendered server-side. But still don't understand why it works by making the screen smaller and then bigger again.
Is there a way I can force the Next.js app to apply the effects on the first render?
Beta Was this translation helpful? Give feedback.
All reactions