---
title: "React Calendar Custom Header Example | Mobiscroll"
component: "Calendar"
framework: "React"
library_version: "6.2.0"
url: "https://demo.mobiscroll.com/react/calendar/customizing-header"
---

# Custom Header - React Calendar demo

Customize the React date picker header — rearrange nav controls, add a today button, or add a week/month view switcher. For React and Next.JS.

- [Live demo](https://demo.mobiscroll.com/react/calendar/customizing-header)
- [View React JS code on GitHub](https://github.com/acidb/mobiscroll-demos-react/tree/main/src/demos/datepicker/calendar/customizing-header)
- [View React TS code on GitHub](https://github.com/acidb/mobiscroll-demos-react-ts/tree/main/src/demos/datepicker/calendar/customizing-header)
- This demo in other frameworks: [JavaScript](https://demo.mobiscroll.com/javascript/calendar/customizing-header.md), [jQuery](https://demo.mobiscroll.com/jquery/calendar/customizing-header.md), [Angular](https://demo.mobiscroll.com/angular/calendar/customizing-header.md), [Vue](https://demo.mobiscroll.com/vue/calendar/customizing-header.md)

## Description

You can customize how the header of calendar looks and how the components are arranged. Besides that you can also add custom functionality, like a segmented control that lets people switch between week and month view.

Use the [`renderCalendarHeader`](https://mobiscroll.com/docs/react/datepicker/api#renderer-renderCalendarHeader) option for passing a custom header layout. There are predefined components - shorthands if you will - that can be used to assemble the header:

- **Navigation component** - `<CalendarNav />`
- **Today button** - `<CalendarToday />`
- **Previous month button** - `<CalendarPrev />`
- **Next month button** - `<CalendarNext />`

## What this demo shows

- The Datepicker calendar header can use the default layout, a custom arrangement, or be hidden completely.
- **Default header**: Displays the current month and year with previous and next navigation controls.
- **Month and year navigation**: Clicking the month and year label opens a picker for navigating directly to a specific month or year.
- **Previous and next controls**: Pages the calendar by one month in month view and one week in week view.
- **Custom header arrangement**: Centers `CalendarNav` and places `CalendarPrev` and `CalendarNext` on opposite sides using predefined calendar components.
- **Today button**: Adds a `CalendarToday` control between the navigation buttons in their default positions.
- **Week and month views**: Adds a segmented control with week and month icons for switching the calendar dynamically between the two views.
- **Selected date preview**: Displays the currently selected date in the header.

## Best for

- **Compact date pickers**: Hide the header when month and year navigation is unnecessary or space is limited.
- **Long-range date selection**: Open the month and year picker to reach dates that would require many previous or next navigation steps.
- **Current-date workflows**: Add a Today button when users frequently need to return to the current date.
- **Flexible date browsing**: Let users switch between week and month views when they need both a focused and a broader calendar view.
- **Selection confirmation**: Show the selected date in the header when users need a clear preview of their current choice.
- **Custom header layouts**: Rearrange the built-in navigation controls to fit the date picker's available space and surrounding interface.

## Tutorial

### Default header

The default header contains the two arrows on the far-right for previous and next months, while the current month indicator with the `CalendarNav` component is placed to the far-left.

```jsx
<Datepicker
    controls={['calendar']}
    calendarType="week"
    calendarSize={2}
/>
```

### Custom header arrangement

You can reorder the controls and place the `CalendarNav` in the middle with the two arrows - `CalendarPrev` and `CalendarNext` - to the sides.

```jsx
const calendarHeader = () => {
    return <React.Fragment>
            <CalendarPrev className="custom-prev" />
            <CalendarNav className="custom-nav" />
            <CalendarNext className="custom-next" />
    </React.Fragment>;
}
<Datepicker
    controls={['calendar']}
    renderCalendarHeader={calendarHeader}
/>
```

### Add a today button

You can also add a custom component, like a `CalendarToday` button.

```jsx
const calendarHeader = () => {
    return <React.Fragment>
        <CalendarNav />
        <div className="custom-buttons">
            <CalendarPrev />
            <CalendarToday />
            <CalendarNext />
        </div>
    </React.Fragment>;
}
<Datepicker
    controls={['calendar']}
    renderCalendarHeader={calendarHeader}
/>
```

### Switch between week and month view

Use a segmented component for creating a view switcher.

```jsx
const [calendarType, setCalendarType] = React.useState('week');
const calendarHeader = () => {
    return <React.Fragment>
        <CalendarNav className="custom-view-nav" />
        <div className="custom-view">
            <SegmentedGroup value={view} onChange={changeView}>
                <SegmentedItem value="week" icon="material-date-range" />
                <SegmentedItem value="month" icon="material-event-note" />
            </SegmentedGroup>             
        </div>
        <CalendarPrev />
        <CalendarNext />
    </React.Fragment>;
}
const changeView = (event) => {
    setCalendarType(event.target.value);
}
<Datepicker
    controls={['calendar']}
    calendarType={calendarType}
    calendarSize={2}
    renderCalendarHeader={calendarHeader}
/>
```

### Preview the selection

Above all that you can give instructions or show the selected `{value}` in the header

```jsx
<Datepicker
    controls={['calendar']}
    calendarType="week"
    calendarSize={2}
    headerText="You selected {value}"
/>
```

## API used in this demo

- [`theme`](https://mobiscroll.com/docs/react/datepicker/api#opt-theme) - option
- [`themeVariant`](https://mobiscroll.com/docs/react/datepicker/api#opt-themeVariant) - option
- [`controls`](https://mobiscroll.com/docs/react/datepicker/api#opt-controls) - option
- [`display`](https://mobiscroll.com/docs/react/datepicker/api#opt-display) - option
- [`calendarType`](https://mobiscroll.com/docs/react/datepicker/api#opt-calendarType) - option
- [`calendarSize`](https://mobiscroll.com/docs/react/datepicker/api#opt-calendarSize) - option
- [`renderCalendarHeader`](https://mobiscroll.com/docs/react/datepicker/api#renderer-renderCalendarHeader) - renderer
- [`headerText`](https://mobiscroll.com/docs/react/datepicker/api#opt-headerText) - option

## Code

### JSX

```jsx
import {
  CalendarNav,
  CalendarNext,
  CalendarPrev,
  CalendarToday,
  Datepicker,
  Segmented,
  SegmentedGroup,
  setOptions,
} from '@mobiscroll/react';
import { useCallback, useState } from 'react';

setOptions({
  theme: 'ios',
  themeVariant: 'light'
});

function App() {
  const [calendarType, setCalendarType] = useState('week');

  const calendarHeaderCustom = useCallback(
    () => (
      <>
        <CalendarPrev className="custom-prev" />
        <CalendarNav className="custom-nav" />
        <CalendarNext className="custom-next" />
      </>
    ),
    [],
  );

  const calendarHeaderToday = useCallback(
    () => (
      <>
        <CalendarNav />
        <div className="custom-buttons">
          <CalendarPrev />
          <CalendarToday />
          <CalendarNext />
        </div>
      </>
    ),
    [],
  );

  const changeView = useCallback((event) => {
    setCalendarType(event.target.value);
  }, []);

  const calendarHeaderSwitch = useCallback(
    () => (
      <>
        <CalendarNav className="custom-view-nav" />
        <div className="custom-view">
          <SegmentedGroup value={calendarType} onChange={changeView}>
            <Segmented value="week" icon="material-date-range" />
            <Segmented value="month" icon="material-event-note" />
          </SegmentedGroup>
        </div>
        <CalendarPrev />
        <CalendarNext />
      </>
    ),
    [calendarType, changeView],
  );

  return (
    <div>
      <Datepicker controls={['calendar']} display="inline" calendarType="week" calendarSize={2} />
      <Datepicker controls={['calendar']} display="inline" renderCalendarHeader={calendarHeaderCustom} />
      <Datepicker controls={['calendar']} display="inline" renderCalendarHeader={calendarHeaderToday} />
      <Datepicker
        controls={['calendar']}
        display="inline"
        calendarType={calendarType}
        calendarSize={2}
        renderCalendarHeader={calendarHeaderSwitch}
      />
      <Datepicker controls={['calendar']} display="inline" calendarType="week" calendarSize={2} headerText="You selected {value}" />
    </div>
  );
}

export default App;
```

### TSX

```tsx
import {
  CalendarNav,
  CalendarNext,
  CalendarPrev,
  CalendarToday,
  Datepicker,
  Segmented,
  SegmentedGroup,
  setOptions,
} from '@mobiscroll/react';
import { ChangeEvent, FC, useCallback, useState } from 'react';

setOptions({
  theme: 'ios',
  themeVariant: 'light'
});

const App: FC = () => {
  const [calendarType, setCalendarType] = useState<'week' | 'year' | 'month' | undefined>('week');

  const calendarHeaderCustom = useCallback(
    () => (
      <>
        <CalendarPrev className="custom-prev" />
        <CalendarNav className="custom-nav" />
        <CalendarNext className="custom-next" />
      </>
    ),
    [],
  );

  const calendarHeaderToday = useCallback(
    () => (
      <>
        <CalendarNav />
        <div className="custom-buttons">
          <CalendarPrev />
          <CalendarToday />
          <CalendarNext />
        </div>
      </>
    ),
    [],
  );

  const changeView = useCallback((event: ChangeEvent<HTMLInputElement>) => {
    setCalendarType(event.target.value as 'week' | 'year' | 'month' | undefined);
  }, []);

  const calendarHeaderSwitch = useCallback(
    () => (
      <>
        <CalendarNav className="custom-view-nav" />
        <div className="custom-view">
          <SegmentedGroup value={calendarType} onChange={changeView}>
            <Segmented value="week" icon="material-date-range" />
            <Segmented value="month" icon="material-event-note" />
          </SegmentedGroup>
        </div>
        <CalendarPrev />
        <CalendarNext />
      </>
    ),
    [calendarType, changeView],
  );

  return (
    <div>
      <Datepicker controls={['calendar']} display="inline" calendarType="week" calendarSize={2} />
      <Datepicker controls={['calendar']} display="inline" renderCalendarHeader={calendarHeaderCustom} />
      <Datepicker controls={['calendar']} display="inline" renderCalendarHeader={calendarHeaderToday} />
      <Datepicker
        controls={['calendar']}
        display="inline"
        calendarType={calendarType}
        calendarSize={2}
        renderCalendarHeader={calendarHeaderSwitch}
      />
      <Datepicker controls={['calendar']} display="inline" calendarType="week" calendarSize={2} headerText="You selected {value}" />
    </div>
  );
};
export default App;
```

### CSS

```css
.custom-buttons,
.custom-view,
.custom-nav {
  display: -webkit-box;
  display: -moz-box;
  display: -ms-flexbox;
  display: flex;
  -webkit-flex: 1 0 auto;
  -moz-box-flex: 1;
  -ms-flex: 1 0 auto;
  flex: 1 0 auto;
}

.custom-buttons {
  -webkit-justify-content: flex-end;
  -moz-box-pack: end;
  -ms-flex-pack: end;
  justify-content: flex-end;
}

.custom-view,
.custom-nav {
  -webkit-justify-content: center;
  -moz-box-pack: center;
  -ms-flex-pack: center;
  justify-content: center;
}

.custom-view-nav .mbsc-calendar-title.mbsc-material {
  font-size: 16px;
}

.custom-view .mbsc-segmented {
  margin: 0;
}

.custom-view .mbsc-segmented.mbsc-material,
.custom-view .mbsc-segmented.mbsc-windows {
  padding: 0 2px;
}

.custom-view .mbsc-segmented .mbsc-segmented-button {
  padding: 0 1px;
}

.custom-view .mbsc-segmented .mbsc-icon {
  font-size: 20px;
}

.custom-view .mbsc-segmented-button.mbsc-windows {
  border: 0;
}
```

## Implementation notes

- Use `controls: ['calendar']` and `display: 'inline'`; the compact multi-row examples add `calendarType: 'week'` and `calendarSize: 2`.
- **Default header**: no extra option needed - it renders the nav label on the left and the prev/next arrows on the right.
- **Custom arrangement**: pass `renderCalendarHeader` (Angular: `calendarHeaderTemplate`, Vue: `#header` slot) returning custom markup that composes the predefined header sub-components - `mbsc-calendar-nav` (Vue: `MbscCalendarNav`, React: `CalendarNav`), `mbsc-calendar-prev`/`mbsc-calendar-next` (Vue: `MbscCalendarPrev`/`MbscCalendarNext`, React: `CalendarPrev`/`CalendarNext`) - in any order/position.
- **Today button**: include `mbsc-calendar-today` (Vue: `MbscCalendarToday`, React: `CalendarToday`) alongside the prev/next controls inside the same custom header markup.
- `calendarType` can be switched at runtime between `'week'` and `'month'`. React/Vue/Angular update it as a controlled value (`useState`, `v-model`, `[(ngModel)]`) bound to the datepicker's `calendarType` prop; JS/jQuery call `.setOptions({ calendarType: 'week' | 'month' })` on the instance.
- **Selected-date preview**: set `headerText` to a template string containing `{value}` (e.g. `'You selected {value}'`) - it's substituted with the current selection and rendered in the header automatically, no custom renderer needed.
- To hide the header entirely, return empty/no markup from `renderCalendarHeader` - pair with a compact layout when month/year navigation isn't needed.

## Run it in your project

1. If not signed up yet, or don't own a license, you can [start a free trial](https://mobiscroll.com/starttrial).

2. Clone the repository:

   ```
   git clone https://github.com/acidb/mobiscroll-demos-react.git
   ```

3. If not installed yet, install the Mobiscroll CLI from NPM:

   ```
   npm install -g @mobiscroll/cli
   ```

4. Config Mobiscroll - open a terminal window in the root directory and run:

   ```
   mobiscroll config react
   ```

5. Install dependencies - open a terminal window in the root directory and run:

   ```
   npm install
   ```

6. Run the project:

   ```
   npm run dev
   ```

On a trial, add `--trial` to the config command: `mobiscroll config react --trial`.

Running a demo locally requires a Mobiscroll trial or a license; setup is per framework at https://mobiscroll.com/docs/react/getting-started/installation

## Related demos

- Previous: [Themes — iOS, Material & Windows](https://demo.mobiscroll.com/react/calendar/themes-ios-material-windows.md) - Style a React calendar date picker with iOS, Material, or Windows themes — switch light/dark mode, use the theme builder, or apply custom CSS.
- Next: [Mark Days with Custom Shapes](https://demo.mobiscroll.com/react/calendar/customize-marked-day-shapes.md) - Add custom-shaped day markers to a React calendar date picker — use the marked option for colored dots, then override styles.
