Customization

Jumbo React Next separates configuration into three layers: the MUI theme (colors, typography, spacing), the layout options (sidebar width, header height, footer visibility), and the global config (route lists, theme composition). This page explains each layer and how to modify it.

Theme configuration

The app theme is assembled by createJumboTheme from four independent region tokens. The root config in src/config/index.ts composes these into a single JumboThemeConfig:

typescript
// src/config/index.ts
import { footerTheme } from '@/themes/footer/default';
import { headerTheme } from '@/themes/header/default';
import { mainTheme } from '@/themes/main/default';
import { sidebarTheme } from '@/themes/sidebar/default';
import { createJumboTheme } from '@jumbo/utilities/helpers';
 
export const CONFIG = {
  THEME: createJumboTheme(mainTheme, headerTheme, sidebarTheme, footerTheme),
  PUBLIC_ROUTES: publicPaths,
  ANONYMOUS_ROUTES: anonymousPaths,
  DISABLE_PROTECTED_ROUTE_CHECK: false,
};

Theme regions

Each region has three mode variants — default (light), dark, and semi-dark — located in src/themes/{region}/:

RegionDefault fileDark fileSemi-dark file
Main (page body)src/themes/main/default.tssrc/themes/main/dark.tssrc/themes/main/semi-dark.ts
Headersrc/themes/header/default.tssrc/themes/header/dark.tssrc/themes/header/semi-dark.ts
Sidebarsrc/themes/sidebar/default.tssrc/themes/sidebar/dark.tssrc/themes/sidebar/semi-dark.ts
Footersrc/themes/footer/default.tssrc/themes/footer/dark.tssrc/themes/footer/semi-dark.ts

To change the primary color for the main region, edit the main theme token file:

typescript
// src/themes/main/default.ts
import { createTheme } from '@mui/material/styles';
 
export const mainTheme = createTheme({
  palette: {
    primary: {
      main: '#7352C7',    // change this to your brand color
      light: '#9E86DB',
      dark: '#3F1D9B',
      contrastText: '#fff',
    },
    // ...
  },
});

Demo-specific themes

Each demo layout (Demo1–Demo4) has its own theme config that extends or overrides the defaults. Demo 4, for example, uses a fully dark stack:

typescript
// src/components/Demo4Layout/themes/index.ts
import { mainThemeDark } from '@/themes/main/dark';
import { headerThemeDark } from '@/themes/header/dark';
import { sidebarThemeDark } from '@/themes/sidebar/dark';
import { footerThemeDark } from '@/themes/footer/dark';
import { createJumboTheme } from '@jumbo/utilities/helpers';
 
export const CONFIG4 = {
  THEME: createJumboTheme(mainThemeDark, headerThemeDark, sidebarThemeDark, footerThemeDark),
};

To create a new theme variant, add a new token file in the appropriate region folder and reference it in your layout's config.

Layout configuration

The (common) layout group uses defaultLayoutConfig from src/config/layouts/default.ts. This object maps to LayoutOptions from @jumbo/types:

typescript
// src/config/layouts/default.ts
const defaultLayoutConfig: LayoutOptions = {
  sidebar: {
    open: true,
    hide: false,
    variant: SIDEBAR_VARIANTS.PERSISTENT,   // 'persistent' | 'temporary' | 'permanent'
    style: SIDEBAR_STYLES.FULL_HEIGHT,      // 'full-height' | 'clipped-under-header'
    view: SIDEBAR_VIEWS.FULL,               // 'full' | 'mini'
    scrollType: SIDEBAR_SCROLL_TYPES.FIXED, // 'fixed' | 'default'
    anchor: SIDEBAR_ANCHOR_POSITIONS.LEFT,  // 'left' | 'right'
    width: 240,
    minWidth: 80,
    drawer: true,
    drawerBreakpoint: 'xl',
  },
  header: {
    hide: false,
    fixed: true,
    sx: { height: 80 },
    drawerBreakpoint: 'xl',
  },
  footer: {
    hide: false,
  },
  content: {
    sx: { py: 4 },
  },
};
 
export const CONTAINER_MAX_WIDTH = 1320;

Layout variant comparison

Layout groupSidebarHeader heightFooterRight sidebar
(common) — defaultPersistent, 240px80pxVisible
(demo1-layout)None130pxVisible
(demo2-layout)Temporary90pxVisible
(demo3-layout)Temporary72pxHiddenEnabled
(demo4-layout)Temporary72pxHiddenEnabled

Changing layout options at runtime

Use the useJumboLayoutSidebarOptions / useJumboLayoutHeaderOptions hooks (from @jumbo/components/JumboLayout) to update options from any component:

typescript
// src/components/SidebarToggleButton/SidebarToggleButton.tsx
'use client';
 
import { useJumboLayoutSidebarOptions } from '@jumbo/components/JumboLayout';
 
export function SidebarToggleButton() {
  const { setSidebarOptions, sidebarOptions } = useJumboLayoutSidebarOptions();
 
  return (
    <button
      onClick={() => setSidebarOptions({ open: !sidebarOptions.open })}
    >
      Toggle Sidebar
    </button>
  );
}

CustomizerSettings drawer

The CustomizerSettings component (src/components/CustomizerSettings/) provides a runtime UI for switching theme modes and layout options. It is rendered inside every layout that uses it:

tsx
// src/app/[lang]/(common)/layout.tsx (excerpt)
import { CustomizerButton } from '@/components/CustomizerButton/CustomizerButton';
import { CustomizerSettings } from '@/components/CustomizerSettings/CustomizerSettings';
 
export default function CommonLayout({ children }) {
  return (
    <JumboLayoutProvider defaultLayoutConfig={defaultLayoutConfig}>
      <JumboLayout header={<Header />} sidebar={<SidebarWithMenus />} footer={<Footer />}>
        {children}
        <CustomizerButton />
        <CustomizerSettings />
      </JumboLayout>
    </JumboLayoutProvider>
  );
}

To hide the customizer in production, remove <CustomizerButton /> and <CustomizerSettings /> from your layout file.

Global config

src/config/index.ts exports the CONFIG object, which is the single source of truth for app-wide settings:

typescript
export const CONFIG: ConfigType = {
  THEME: createJumboTheme(mainTheme, headerTheme, sidebarTheme, footerTheme),
  PUBLIC_ROUTES: publicPaths,       // routes accessible without authentication
  ANONYMOUS_ROUTES: anonymousPaths, // routes that redirect authenticated users away
  DISABLE_PROTECTED_ROUTE_CHECK: false, // set to true to bypass auth in development
};

The route lists are defined in src/config/routes/path.ts and used by the proxy handlers in src/proxy/ to determine how to handle each incoming request. See the Proxy & Middleware guide for details.