Setup

Simple instructions for integrating into an existing project.

This example builds on next-app-dir.

For version v2.


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-variable/public-sans @mui/lab @mui/material @mui/material-nextjs @mui/x-date-pickers

Dev dependencies
npm i -D @types/node

Step 3: Modifying files (Copy from the code we provided).

  • 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 = {
  assetsDir: process.env.NEXT_PUBLIC_ASSETS_DIR ?? '',
};

src/global.css
/** **************************************
* Fonts: app
*************************************** */
@import '@fontsource-variable/public-sans';
 
@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';
 
/** **************************************
* Baseline
*************************************** */
html {
  height: 100%;
  -webkit-overflow-scrolling: touch;
}
body,
#root,
#root__layout {
  display: flex;
  flex: 1 1 auto;
  min-height: 100%;
  flex-direction: column;
}
img {
  max-width: 100%;
  vertical-align: middle;
}
ul {
  margin: 0;
  padding: 0;
  list-style-type: none;
}
input[type='number'] {
  -moz-appearance: textfield;
  appearance: none;
}
input[type='number']::-webkit-outer-spin-button {
  margin: 0;
  -webkit-appearance: none;
}
input[type='number']::-webkit-inner-spin-button {
  margin: 0;
  -webkit-appearance: none;
}

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
import { defaultSettings } from 'src/components/settings';
 
export const schemeConfig = {
  modeStorageKey: 'theme-mode',
  defaultMode: 'light',
};

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 { schemeConfig } from 'src/theme/scheme-config';
import InitColorSchemeScript from '@mui/material/InitColorSchemeScript';
 
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>
        <InitColorSchemeScript
          defaultMode={schemeConfig.defaultMode}
          modeStorageKey={schemeConfig.modeStorageKey}
        />
 
        <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>
  );
}