How can you utilize Material UI's `useMediaQuery` in the `/app` route of NextJs (13.4) in order to prevent flashing?

I've been working on a Next.js project and using the 'app' router to create a consistent layout for all pages. As part of handling responsive design, I incorporated Material-UI (MUI) and its useMediaQuery hook. However, when loading a page, I'm experiencing a slight issue where there's a momentary flash of the mobile version on desktop devices during the initial rendering.

Below is an overview of my current setup:

  1. MUI with NextJS 13.4.4 /app route.
  2. Utilizing Client Component By "use client"; directives in NextJS.

Here is the code snippet:

 "use client";
import { useState } from "react";
import { NextLinkComposed } from "../Link";
import { useTheme } from "@mui/material/styles";
import { drawerWidth } from "@/utils/constraints";
import {
  List,
  ListItem,
  ListItemButton,
  ListItemIcon,
  ListItemText,
  Drawer,
  Box,
  useMediaQuery,
  InputAdornment,
  OutlinedInput,
} from "@mui/material";
import {
  GroupsOutlined as GroupsIcon,
  DashboardOutlined as DashboardIcon,
  Search as SearchIcon,
} from "@mui/icons-material";

// Function component definition omitted for brevity

const SideBarItems = [
  {
    name: "Dashboard",
    path: "/dashboard",
    icon: DashboardIcon,
  },
  { name: "Users", path: "/user", icon: GroupsIcon },
];

I would greatly appreciate any assistance or insights regarding this issue.

Thank you.

Answer ā„–1

In dealing with this issue, I have come up with a workaround that involves using an app router and SSG rendering technique. This method is based on information found in the MUI official documentation (https://mui.com/material-ui/guides/next-js-app-router/#next-js-and-react-server-components).

To implement this approach successfully, it is necessary to establish a state in localStorage labeled as deviceWidth during the initial loading phase. Since localStorage operates synchronously, there are no blocking issues to be concerned about.

ThemeProvider.tsx

"use client";
import createCache from "@emotion/cache";
import { useServerInsertedHTML } from "next/navigation";
import { CacheProvider } from "@emotion/react";
import { ThemeProvider, createTheme } from "@mui/material/styles";
import CssBaseline from "@mui/material/CssBaseline";
import React from "react";
import mediaQuery from "css-mediaquery";

const theme = createTheme({
  components: {
    MuiUseMediaQuery: {
      defaultProps: {
        ssrMatchMedia: (query) => ({
          matches: mediaQuery.match(query, {
            // The estimated CSS width of the browser.
            width: localStorage.getItem("deviceWidth") || 1200, // Include this default value
          }),
        }),
      },
    },
  },
});

export default function ThemeRegistry(props: any) {
  const { options, children } = props;

  const [{ cache, flush }] = React.useState(() => {
    const cache = createCache(options);
    cache.compat = true;
    const prevInsert = cache.insert;
    let inserted: string[] = [];
    cache.insert = (...args) => {
      const serialized = args[1];
      if (cache.inserted[serialized.name] === undefined) {
        inserted.push(serialized.name);
      }
      return prevInsert(...args);
    };
    const flush = () => {
      const prevInserted = inserted;
      inserted = [];
      return prevInserted;
    };
    return { cache, flush };
  });

  useServerInsertedHTML(() => {
    const names = flush();
    if (names.length === 0) {
      return null;
    }
    let styles = "";
    for (const name of names) {
      styles += cache.inserted[name];
    }
    return (
      <style
        key={cache.key}
        data-emotion={`${cache.key} ${names.join(" ")}`}
        dangerouslySetInnerHTML={{
          __html: styles,
        }}
      />
    );
  });

  return (
    <CacheProvider value={cache}>
      <ThemeProvider theme={theme}>
        <CssBaseline />
        {children}
      </ThemeProvider>
    </CacheProvider>
  );
}

layout.tsx

import ThemeRegistry from "./ThemeRegistry";
  import "./styles.css";

  export default function RootLayout({
    children,
  }: {
    children: React.ReactNode;
  }) {
    return (
      <html lang="en">
        <head>
        </head>
        <body>
          <ThemeRegistry options={{ key: "mui" }}>{children}</ThemeRegistry>
        </body>
      </html>
    );
  }

Answer ā„–2

One method you may consider is utilizing the mui hidden component approach, which can be found here. By creating two distinct drawers and employing the sx props to hide them based on breakpoints.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Switch the visibility of a div tag using Next.js

Script export default function Navigation(){ let displayMenu = false; function toggleMenu() { displayMenu = !displayMenu; } return ( <> <button onClick={toggleMenu}>Toggle Navigation</button> {/*This code sh ...

Enhance the Material UI Data Grid by customizing the toolbar's default slots with the option to disable the

https://i.stack.imgur.com/0YV9m.png Background In my current project, I am utilizing the Datagrid component from MUI [email protected]. I have disabled the column menu to display the toolbar at the top of the table instead of on individual columns. ...

What are some ways to implement a pre-execution step, such as an interceptor, before Nextjs runs getStatic

When working with getStaticProps and getServerSideProps in Next.js, I need to intercept and add common header properties to all request calls that are executed server-side. axios.interceptors.request.use(function (config) { // Perform actions before ...

Map failing to refresh

Having some trouble with the map function as it's not updating my select box with the new selected value. The issue occurs within a material UI dialog that appears when viewing a file. I notice that the values get updated only after closing and reopen ...

I'm wondering, on a storybook, where is the best place to set my MUI X license key

Can you help with where to specify my license key in Storybook? I need guidance on where to set the license key in Storybook. According to MUI Docs, it should be done before React renders the first component and only once in the application. However, I ...

Is there a way to personalize the appearance of Static File in nextjs?

Is there a way to customize the display of static files, particularly images? For instance, when accessing a static file on a website like this: Currently, it just shows a basic img element. Is it possible to dynamically add additional elements to that d ...

Leverage the power of express-session in your NextJS project

Currently, I am working on developing a login system using NextJS and MySQL. I am looking to implement sessions for user login, but I am unsure of how to integrate express-session with NextJS. Can anyone provide guidance on whether express-session can be ...

I am trying to figure out how to properly utilize server-only functions within Next.js middleware

In my current project, I am utilizing Next.js 13 along with the App Router feature. While attempting to include a server-specific fetch function in middleware.js, an error message is encountered: Error: Unable to import this module from a Client Compone ...

Adjust CardMedia Images to match their content in the new MUI 5 version

Iā€™m looking to have my images fully fill the CardMedia component. However, because they are of varying sizes, some end up being cropped like this: https://i.stack.imgur.com/JHIrT.png Additionally, when resizing the images, some get cut off as well: ht ...

The MUI Module is missing: Unable to locate '@emotion/react'

Attempted this solution, but unfortunately it did not work Currently using the latest version of Material-UI Error: Module not found: Can't resolve '@emotion/react' Let's try installing it then.. npm i @emotion/react @emotion/style ...

Issues with zDepth functionality in Material-UI (React.js) not being functional

Can anyone explain the concept of zDepth to me? I have a component with the following render method: render() { return ( <div> <AppBar zDepth={2} title="Some title" iconElementLeft={<IconButton onClick={this ...

What is the best method to display a tooltip for a disabled radio button within a set of radio buttons?

Is there a way to disable a specific radio button based on a condition and display a tooltip only for that disabled button? https://i.stack.imgur.com/niZK1.png import {Tooltip} from '@mui/material'; <Tooltip titl ...

Step-by-step guide for launching a Next.js/Node application

Currently, I am developing a full-stack project utilizing a next.js application for the front-end and a node/express server for the API. The front-end and back-end are running on separate ports. Here is how my application is configured: https://i.stack.im ...

The Material UI button shifts to a different row

I need help adjusting the spacing between text and a button on my webpage. Currently, they are too close to each other with no space in between. How can I add some space without causing the button to move to the next line? const useStyles = makeStyles((the ...

NextAuth encountered a CLIENT_FETCH_ERROR error while processing the session callback

Encountering issues while trying to set up nextauth v4. Keep getting this error: Client fetch error, Unexpected end of JSON input {error: {ā€¦}, path: 'session', message: 'JSON.parse: unexpected end of data at line 1 column 1 of the JSON d ...

What is causing styled-components to include my attributes in the DOM?

In various parts of my code, there is a snippet like this: import React from 'react' import styled from 'styled-components' type PropsType = { direction?: 'horizontal' | 'vertical' flex?: number | string width ...

Setting up user roles using Firebase Auth in NextJS application

Seeking a solution to implement a multi-level role system for my blog website. Currently utilizing Firebase Auth for authentication with email/password, but all users have the same posting/editing access. Looking to differentiate between Admins, Moderators ...

Electronic circuit embedded within a material-textured text field offering multiline functionality

While experimenting with TagsInput, I came across this helpful snippet on codesandbox that you can check out here. The challenge I encountered is when there are numerous chips, they extend beyond the boundaries of the text field. My goal is to implement ...

The onScroll event is failing to trigger when scrolling to a particular div on Next.js

Is there a way to fetch data when a specific div comes into view on a SSR page in Next.js? I attempted using the onScroll event on the div, but it doesn't seem to be triggering. Any suggestions? function handleScroll() { console.log("scrolled ...

Resolve problems with implementing dynamic routes in Next.js

I have been learning about Next.js and I am struggling with understanding how to set up dynamic routing. I have the following setup: https://i.stack.imgur.com/uBPdm.png https://i.stack.imgur.com/YYSxn.png "use client" import React from "reac ...