Setup


Step 1: Create new app next.js

npx create-next-app@latest

# What is your project named? …
 my-app
# Would you like to use TypeScript? …
 Yes # Or "No" if using JavaScript.
# Would you like to use ESLint? …
 No
# Would you like to use Tailwind CSS? …
 No
# Would you like to use `src/` directory? …
 Yes
# Would you like to use App Router? (recommended) …
 Yes
# Would you like to customize the default import alias (@/*)?
 Yes
# What import alias would you like configured? …
 src/*

Step 2: Install dependencies

Dependencies
npm i @emotion/cache @emotion/react @emotion/styled @fontsource/barlow @fontsource/public-sans @mui/lab @mui/material @mui/material-nextjs @mui/x-data-grid @mui/x-date-pickers @mui/x-tree-view

Dev dependencies
npm i --save-dev @types/node

Step 3: Modifying files

  • Copy and override tsconfig.json / jsconfig.json.
  • Copy src/theme.
  • Remove src/theme/with-settings/**.

Step 4: Create files

src/config-global.ts
export const CONFIG = {
  site: {
    basePath: process.env.NEXT_PUBLIC_BASE_PATH ?? '',
  },
};

src/global.css
@import '@fontsource/public-sans/400.css';
@import '@fontsource/public-sans/500.css';
@import '@fontsource/public-sans/600.css';
@import '@fontsource/public-sans/700.css';
@import '@fontsource/public-sans/800.css';
 
@import '@fontsource/barlow/400.css';
@import '@fontsource/barlow/500.css';
@import '@fontsource/barlow/600.css';
@import '@fontsource/barlow/700.css';
@import '@fontsource/barlow/800.css';

Step 5: Update theme

src/theme/create-theme.ts
export function createTheme(): Theme {
  const initialTheme = {
    colorSchemes,
    shadows: shadows('light'),
    customShadows: customShadows('light'),
    shape: { borderRadius: 8 },
    components,
    typography,
    cssVarPrefix: '',
    shouldSkipGeneratingVar,
  };
 
  const theme = extendTheme(initialTheme);
 
  return theme;
}

src/theme/color-scheme-script.ts
'use client';
 
import { getInitColorSchemeScript as _getInitColorSchemeScript } from '@mui/material/styles';
 
export const schemeConfig = {
  modeStorageKey: 'theme-mode',
  defaultMode: 'light',
} as const;
 
export const getInitColorSchemeScript = _getInitColorSchemeScript(schemeConfig);

src/theme/theme-provider.tsx
export function ThemeProvider({ children }: Props) {
  const theme = createTheme();
 
  return (
    <AppRouterCacheProvider options={{ key: 'css' }}>
      <CssVarsProvider
        theme={theme}
        defaultMode={schemeConfig.defaultMode}
        modeStorageKey={schemeConfig.modeStorageKey}
      >
        <CssBaseline />
        {children}
      </CssVarsProvider>
    </AppRouterCacheProvider>
  );
}

Step 6: Testing

src/app/layout.tsx
import 'src/global.css';
 
import type { Metadata } from 'next';
 
import { ThemeProvider } from 'src/theme/theme-provider';
import { getInitColorSchemeScript } from 'src/theme/color-scheme-script';
 
export const metadata: Metadata = {
  title: 'Create Next App',
  description: 'Generated by create next app',
};
 
export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en" suppressHydrationWarning>
      <body>
        {getInitColorSchemeScript}
        <ThemeProvider>{children}</ThemeProvider>
      </body>
    </html>
  );
}
 

src/app/page.tsx
import Stack from '@mui/material/Stack';
import Button from '@mui/material/Button';
 
export default function Home() {
  return (
    <Stack spacing={1} alignItems="center">
      <Button variant="contained">Button</Button>
      <Button variant="contained" color="primary">
        Button
      </Button>
      <Button variant="contained" color="secondary">
        Button
      </Button>
      <Button variant="contained" color="info">
        Button
      </Button>
      <Button variant="contained" color="success">
        Button
      </Button>
      <Button variant="contained" color="warning">
        Button
      </Button>
      <Button variant="contained" color="error">
        Button
      </Button>
      <Button disabled variant="contained">
        Button
      </Button>
    </Stack>
  );
}