<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Arshad Ali Soomro</title>
    <description>The latest articles on DEV Community by Arshad Ali Soomro (@arshadalisoomro).</description>
    <link>https://dev.to/arshadalisoomro</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1057778%2F9318e337-c7ef-4c04-9c85-25125869a900.png</url>
      <title>DEV Community: Arshad Ali Soomro</title>
      <link>https://dev.to/arshadalisoomro</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/arshadalisoomro"/>
    <language>en</language>
    <item>
      <title>Adding Material UI to Next.js TypeScript</title>
      <dc:creator>Arshad Ali Soomro</dc:creator>
      <pubDate>Mon, 03 Apr 2023 08:19:26 +0000</pubDate>
      <link>https://dev.to/arshadalisoomro/adding-material-ui-to-nextjs-typescript-28bg</link>
      <guid>https://dev.to/arshadalisoomro/adding-material-ui-to-nextjs-typescript-28bg</guid>
      <description>&lt;p&gt;&lt;a href="https://mui.com/"&gt;Mui&lt;/a&gt; is a popular UI component library for React that provides pre-made components such as buttons, forms, and modals. In this article, we will be discussing how to add Mui v5 to Next.js using TypeScript.&lt;/p&gt;

&lt;h2&gt;
  
  
  Install Dependencies
&lt;/h2&gt;

&lt;p&gt;First, you need to install the necessary dependencies. You can do this by running the following command in your VS Code terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yarn add @mui/material @mui/icons-material @emotion/react @emotion/server @emotion/styled
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Create a &lt;code&gt;createEmotionCache.ts&lt;/code&gt; File
&lt;/h2&gt;

&lt;p&gt;The next step is to create a &lt;code&gt;createEmotionCache.ts&lt;/code&gt; file in your src folder. This is a utility function provided by Material-UI (mui) to create a cache for Emotion, which is a CSS-in-JS library used by Material-UI (mui) for styling. The cache is used to store generated class names and prevent duplicate style declarations.&lt;/p&gt;

&lt;p&gt;Here's a required implementation of &lt;code&gt;createEmotionCache.ts&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import createCache from '@emotion/cache';

const isBrowser = typeof document !== 'undefined';

// On the client side, Create a meta tag at the top of the &amp;lt;head&amp;gt; and set it as insertionPoint.
// This assures that MUI styles are loaded first.
// It allows developers to easily override MUI styles with other styling solutions, like CSS modules.
export default function createEmotionCache() {
  let insertionPoint;

  if (isBrowser) {
    const emotionInsertionPoint = document.querySelector&amp;lt;HTMLMetaElement&amp;gt;(
      'meta[name="emotion-insertion-point"]',
    );
    insertionPoint = emotionInsertionPoint ?? undefined;
  }

  return createCache({ key: 'mui-style', insertionPoint });
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Create a &lt;code&gt;theme.ts&lt;/code&gt; File
&lt;/h2&gt;

&lt;p&gt;The next step is to create a &lt;code&gt;theme.ts&lt;/code&gt; file in your src folder. This file contains the main theme configuration for your app.&lt;/p&gt;

&lt;p&gt;Here's a required implementation of &lt;code&gt;theme.ts&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Roboto } from 'next/font/google';
import { createTheme } from '@mui/material/styles';
import { red } from '@mui/material/colors';

export const roboto = Roboto({
  weight: ['300', '400', '500', '700'],
  subsets: ['latin'],
  display: 'swap',
  fallback: ['Helvetica', 'Arial', 'sans-serif'],
});

// Create a theme instance.
const theme = createTheme({
  palette: {
    primary: {
      main: '#556cd6',
    },
    secondary: {
      main: '#19857b',
    },
    error: {
      main: red.A400,
    },
  },
  typography: {
    fontFamily: roboto.style.fontFamily,
  },
});

export default theme;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Edit &lt;code&gt;_app.tsx&lt;/code&gt; File
&lt;/h2&gt;

&lt;p&gt;Next, you need to edit &lt;code&gt;_app.tsx&lt;/code&gt; file in the projects src/pages folder. This file is used to wrap your app in a higher-order component (HOC) that provides global styles and theme settings.&lt;/p&gt;

&lt;p&gt;Here's a required implementation of &lt;code&gt;_app.tsx&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import * as React from 'react';
import Head from 'next/head';
import { AppProps } from 'next/app';
import { ThemeProvider } from '@mui/material/styles';
import CssBaseline from '@mui/material/CssBaseline';
import { CacheProvider, EmotionCache } from '@emotion/react';
import createEmotionCache from '@/createEmotionCache';
import theme from '@/theme';

// Client-side cache, shared for the whole session of the user in the browser.
const clientSideEmotionCache = createEmotionCache();

export interface EmployeeLeaveManagerProps extends AppProps {
  emotionCache?: EmotionCache;
}

export default function EmployeeLeaveManagerApp(props: EmployeeLeaveManagerProps) {
  const { Component, emotionCache = clientSideEmotionCache, pageProps } = props;
  return (
    &amp;lt;CacheProvider value={emotionCache}&amp;gt;
      &amp;lt;Head&amp;gt;
        &amp;lt;meta name="viewport" content="initial-scale=1, width=device-width" /&amp;gt;
      &amp;lt;/Head&amp;gt;
      &amp;lt;ThemeProvider theme={theme}&amp;gt;
        {/* CssBaseline kickstart an elegant, consistent, and simple baseline to build upon. */}
        &amp;lt;CssBaseline /&amp;gt;
        &amp;lt;Component {...pageProps} /&amp;gt;
      &amp;lt;/ThemeProvider&amp;gt;
    &amp;lt;/CacheProvider&amp;gt;
  );
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Edit &lt;code&gt;_document.tsx&lt;/code&gt; File
&lt;/h2&gt;

&lt;p&gt;In Next.js, the &lt;code&gt;_document.tsx&lt;/code&gt; file is a special file used for server-side rendering (SSR) and to override the default &lt;code&gt;Document&lt;/code&gt; component provided by Next.js.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;Document&lt;/code&gt; component in Next.js is responsible for rendering the initial HTML document for the app, including the &lt;code&gt;&amp;lt;html&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt;, and &lt;code&gt;&amp;lt;body&amp;gt;&lt;/code&gt; tags. It is used during server-side rendering to generate the HTML that is sent to the client.&lt;/p&gt;

&lt;p&gt;By default, Next.js provides a &lt;code&gt;Document&lt;/code&gt; component that renders a minimal HTML document with some Next.js specific scripts and styles. However, in some cases, you may want to customize the HTML document, for example, by adding custom scripts, styles, or meta tags.&lt;/p&gt;

&lt;p&gt;Here's a required implementation of &lt;code&gt;_document.tsx&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import * as React from 'react';
import Document, {
  Html,
  Head,
  Main,
  NextScript,
  DocumentProps,
  DocumentContext,
} from 'next/document';
import createEmotionServer from '@emotion/server/create-instance';
import { AppType } from 'next/app';
import { EmployeeLeaveManagerProps } from './_app';
import theme, { roboto } from '@/theme';
import createEmotionCache from '@/createEmotionCache';

interface EmployeeLeaveManagerDocumentProps extends DocumentProps {
  emotionStyleTags: JSX.Element[];
}

export default function EmployeeLeaveManagerDocument({ emotionStyleTags }: EmployeeLeaveManagerDocumentProps) {
  return (
    &amp;lt;Html lang="en" className={roboto.className}&amp;gt;
      &amp;lt;Head&amp;gt;
        {/* PWA primary color */}
        &amp;lt;meta name="theme-color" content={theme.palette.primary.main} /&amp;gt;
        &amp;lt;link rel="shortcut icon" href="/favicon.ico" /&amp;gt;
        &amp;lt;meta name="emotion-insertion-point" content="" /&amp;gt;
        {emotionStyleTags}
      &amp;lt;/Head&amp;gt;
      &amp;lt;body&amp;gt;
        &amp;lt;Main /&amp;gt;
        &amp;lt;NextScript /&amp;gt;
      &amp;lt;/body&amp;gt;
    &amp;lt;/Html&amp;gt;
  );
}

// `getInitialProps` belongs to `_document` (instead of `_app`),
// it's compatible with static-site generation (SSG).
EmployeeLeaveManagerDocument.getInitialProps = async (ctx: DocumentContext) =&amp;gt; {
  // Resolution order
  //
  // On the server:
  // 1. app.getInitialProps
  // 2. page.getInitialProps
  // 3. document.getInitialProps
  // 4. app.render
  // 5. page.render
  // 6. document.render
  //
  // On the server with error:
  // 1. document.getInitialProps
  // 2. app.render
  // 3. page.render
  // 4. document.render
  //
  // On the client
  // 1. app.getInitialProps
  // 2. page.getInitialProps
  // 3. app.render
  // 4. page.render

  const originalRenderPage = ctx.renderPage;

  // You can consider sharing the same Emotion cache between all the SSR requests to speed up performance.
  // However, be aware that it can have global side effects.
  const cache = createEmotionCache();
  const { extractCriticalToChunks } = createEmotionServer(cache);

  ctx.renderPage = () =&amp;gt;
    originalRenderPage({
      enhanceApp: (App: React.ComponentType&amp;lt;React.ComponentProps&amp;lt;AppType&amp;gt; &amp;amp; EmployeeLeaveManagerProps&amp;gt;) =&amp;gt;
        function EnhanceApp(props) {
          return &amp;lt;App emotionCache={cache} {...props} /&amp;gt;;
        },
    });

  const initialProps = await Document.getInitialProps(ctx);
  // This is important. It prevents Emotion to render invalid HTML.
  // See https://github.com/mui/material-ui/issues/26561#issuecomment-855286153
  const emotionStyles = extractCriticalToChunks(initialProps.html);
  const emotionStyleTags = emotionStyles.styles.map((style) =&amp;gt; (
    &amp;lt;style
      data-emotion={`${style.key} ${style.ids.join(' ')}`}
      key={style.key}
      // eslint-disable-next-line react/no-danger
      dangerouslySetInnerHTML={{ __html: style.css }}
    /&amp;gt;
  ));

  return {
    ...initialProps,
    emotionStyleTags,
  };
};

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Import Mui Components
&lt;/h2&gt;

&lt;p&gt;Now that you have set up your custom required files, you can start importing Mui components into your pages or other components. For example mui &lt;code&gt;Button&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import Head from 'next/head'
import Box from '@mui/material/Box'
import Button from '@mui/material/Button'

export default function Home() {
  return (
    &amp;lt;&amp;gt;
      &amp;lt;Head&amp;gt;
        &amp;lt;title&amp;gt;Employee Leave Manager App&amp;lt;/title&amp;gt;
        &amp;lt;meta name="description" content="Generated by create next app" /&amp;gt;
        &amp;lt;meta name="viewport" content="width=device-width, initial-scale=1" /&amp;gt;
        &amp;lt;link rel="icon" href="/favicon.ico" /&amp;gt;
      &amp;lt;/Head&amp;gt;
      &amp;lt;Box&amp;gt;
        &amp;lt;Button variant="contained"&amp;gt;
          MUI Button
        &amp;lt;/Button&amp;gt;
      &amp;lt;/Box&amp;gt;
    &amp;lt;/&amp;gt;
  )
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Adding MUI to your Next.js TypeScript project can be a powerful way to quickly add pre-made UI components and styles. By following the steps in this article, you should now have a good foundation for integrating MUI into your app.&lt;/p&gt;

&lt;p&gt;For reference visit &lt;a href="https://github.com/mui/material-ui/tree/master/examples/material-next-ts"&gt;https://github.com/mui/material-ui/tree/master/examples/material-next-ts&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>nextjs</category>
      <category>react</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
