Project dashboard with active projects, team members, project status table, charts, and React sidebar code snippet

Technical Blog Article — App 48: Navigable Sidebar with React, TypeScript, Fluent UI, and Vite

Introduction

In modern enterprise applications, navigation is one of the most important architectural elements. Before users interact with dashboards, reports, CRM systems, SharePoint portals, ticket systems, analytics pages, or administrative panels, they first interact with navigation.

This is why sidebar layouts are extremely common in professional React applications.

In App 48 — Navigable Sidebar, we build a Microsoft-style enterprise navigation system using:

  • React
  • TypeScript
  • Vite
  • Fluent UI
  • React state
  • component composition
  • declarative rendering

This application belongs to Block 3 — Fluent UI Professional Applications, where the focus evolves from simple UI rendering into enterprise layout architecture and Microsoft-style component systems.

The app introduces:

  • dynamic navigation rendering
  • controlled selection state
  • enterprise sidebar layouts
  • Fluent UI navigation buttons
  • TypeScript-driven UI architecture
  • state-driven content rendering
  • reusable layout composition

Most importantly, this app reinforces one of the most important React concepts:

UI is derived from state.

The selected menu item exists in React state, and the visible content automatically changes according to that state.


1. What This App Teaches

This app introduces several critical React architecture concepts.

ConceptPurpose
useStateStores the selected navigation item
map() renderingConverts data into navigation buttons
TypeScript interfacesDefines predictable navigation structure
Component compositionSplits layout into focused components
Fluent UI ButtonsCreates enterprise navigation UI
Conditional appearanceHighlights active navigation item
Derived UIContent changes according to state
Flexbox layoutCreates sidebar + content layout

The central mental model is:

Navigation selection
→ React state changes
→ React re-renders
→ UI updates automatically

This is declarative rendering.


2. Create the Project

PowerShell commands:

cd C:\ReactApps
New-Item bloco03 -ItemType Directory
cd bloco03
npm create vite@latest app48-navigable-sidebar -- --template react-ts
cd app48-navigable-sidebar
npm install
npm install @fluentui/react-components @fluentui/react-icons

Create folders:

New-Item src\components -ItemType Directory
New-Item src\models -ItemType Directory
New-Item src\data -ItemType Directory
New-Item src\styles -ItemType Directory

Create files:

New-Item src\models\NavigationItem.ts -ItemType File
New-Item src\data\navigationItems.ts -ItemType File
New-Item src\components\Sidebar.tsx -ItemType File
New-Item src\components\PageContent.tsx -ItemType File
New-Item artigo.md -ItemType File

3. Final Folder Structure

app48-navigable-sidebar/
src/
components/
Sidebar.tsx
PageContent.tsx
data/
navigationItems.ts
models/
NavigationItem.ts
styles/
App.tsx
main.tsx
index.css
artigo.md
package.json
vite.config.ts

This structure is important because enterprise React applications must separate responsibilities clearly.

FileResponsibility
NavigationItem.tsDefines navigation data structure
navigationItems.tsStores navigation data
Sidebar.tsxRenders navigation menu
PageContent.tsxRenders current selected page
App.tsxOwns navigation state
main.tsxConnects React to the browser
index.cssGlobal CSS reset

4. Understanding the Navigation Model

src\models\NavigationItem.ts

export type NavigationIconKey =
| "dashboard"
| "users"
| "documents"
| "analytics"
| "settings";
export interface NavigationItem {
id: string;
label: string;
description: string;
iconKey: NavigationIconKey;
}

This file defines the structure of each navigation item.

Each item contains:

PropertyPurpose
idUnique identifier
labelNavigation button text
descriptionMain content description
iconKeyDetermines which icon to render

This is important because enterprise React applications should avoid unstructured objects.

TypeScript guarantees:

  • predictable architecture
  • safer refactoring
  • autocomplete
  • compile-time validation

5. Why navigationItems.ts Uses .ts Instead of .tsx

One extremely important correction in this app is:

navigationItems.ts

instead of:

navigationItems.tsx

Why?

Because this file stores only data.

It does NOT contain JSX.

Correct architecture:

File TypePurpose
.tsData, types, interfaces
.tsxReact components with JSX

This is critical in React + TypeScript projects.


6. Understanding Navigation Data

src\data\navigationItems.ts

import type { NavigationItem } from "../models/NavigationItem";

The file exports:

export const navigationItems: NavigationItem[]

This creates a typed array.

Example item:

{
id: "dashboard",
label: "Dashboard",
description: "Enterprise overview with KPIs and activity summary.",
iconKey: "dashboard",
}

This follows one of the most important React principles:

The UI should be derived from data.

Instead of manually creating navigation buttons one by one, React converts data into UI.


7. Understanding Sidebar.tsx

The sidebar component is responsible for rendering navigation.

Imports:

import {
Button,
Card,
Text,
Title2,
} from "@fluentui/react-components";

This app uses Fluent UI as the Microsoft enterprise design system.

Fluent UI provides:

  • accessibility
  • keyboard navigation
  • enterprise styling
  • typography consistency
  • spacing systems
  • Microsoft visual identity

Official documentation:


8. Understanding getNavigationIcon

function getNavigationIcon(iconKey: NavigationIconKey)

This function converts a string into a React icon component.

Example:

case "dashboard":
return <Home24Regular />;

This is extremely important architecturally.

Instead of storing JSX inside the data file:

icon: <Home24Regular />

we store only:

iconKey: "dashboard"

Then the React component decides how to render it.

This keeps:

  • data clean
  • rendering logic centralized
  • architecture more maintainable

9. Why JSX Must Stay Inside .tsx

One of the biggest lessons from this app is:

JSX belongs in .tsx files.

This is JSX:

<Home24Regular />

JSX is React syntax.

Therefore it must exist only inside:

  • React components
  • .tsx files

This separation improves:

  • readability
  • architecture
  • maintainability

10. Understanding the Sidebar Layout

The sidebar uses:

<Card>

as the main navigation container.

Styles:

width: "280px",
minHeight: "100vh",
display: "flex",
flexDirection: "column",
gap: "16px",

This creates the classic enterprise layout:

-----------------------------------
| ReactLab |
| Enterprise Navigation |
| |
| Dashboard |
| Users |
| Documents |
| Analytics |
| Settings |
-----------------------------------

11. Understanding map() Rendering

The navigation buttons are generated dynamically:

{items.map((item) => (

This is one of the most important React patterns.

React converts:

navigationItems[]

into:

<Button />
<Button />
<Button />

Conceptually:

data
→ React rendering
→ UI

Instead of manually creating every button, the UI derives from data.

Official documentation:


12. Why key={item.id} Matters

key={item.id}

React requires stable keys for lists.

Keys help React:

  • identify elements
  • update efficiently
  • preserve correct rendering

Without keys:

  • React shows warnings
  • updates become less predictable

Keys are critical in enterprise rendering systems.


13. Understanding Navigation State

Inside App.tsx:

const [selectedId, setSelectedId] =
useState("dashboard");

This is the heart of the application.

The selected menu item is stored in React state.

This means:

  • React remembers the selected section
  • the UI updates automatically
  • rendering becomes predictable

Official documentation:


14. Understanding the Navigation Flow

The rendering flow is:

User clicks sidebar button
→ onClick fires
→ setSelectedId updates state
→ React re-renders App
→ selectedItem changes
→ PageContent receives new props
→ visible content updates

This is React’s declarative model.

We do NOT manually manipulate the DOM.


15. Understanding Derived Data

Inside App.tsx:

const selectedItem =
navigationItems.find(
(item) => item.id === selectedId
) ?? navigationItems[0];

This is derived data.

React calculates:

  • which item matches the selected ID

Notice something important:

selectedItem is NOT stored in state.

It is derived from:

  • selectedId
  • navigationItems

This follows official React guidance:

Avoid redundant state.

Official documentation:


16. Understanding Conditional Appearance

The sidebar highlights the selected item:

appearance={
selectedId === item.id
? "primary"
: "subtle"
}

This means:

  • selected button = primary appearance
  • unselected buttons = subtle appearance

This is conditional rendering.

The UI changes according to state.


17. Understanding PageContent.tsx

This component displays the selected section.

Props:

interface PageContentProps {
selectedItem: NavigationItem;
}

This means:

  • the parent decides what page is active
  • PageContent simply renders it

This is component composition.

React applications scale by passing data through props.

Official documentation:


18. Understanding the Main Layout

App.tsx uses:

display: "flex"

This creates the enterprise structure:

-----------------------------------------
| Sidebar | Main Content |
| | |
| | |
-----------------------------------------

The sidebar has fixed width:

width: "280px"

The content area uses:

flex: 1

meaning:

Take all remaining available space.

This is classic enterprise dashboard architecture.


19. Understanding main.tsx

The React entry point:

ReactDOM.createRoot(
document.getElementById("root")!
)

connects React to:

<div id="root"></div>

inside index.html.

Then:

<FluentProvider theme={webLightTheme}>

activates the Microsoft Fluent UI design system globally.

This provides:

  • typography
  • colors
  • spacing
  • accessibility
  • enterprise visual consistency

20. Why There Is No useEffect

This app intentionally does NOT use useEffect.

Why?

Because:

  • no API exists
  • no timer exists
  • no external synchronization exists

The UI is fully driven by local state.

Therefore:

useState is sufficient.

This follows React guidance:

You Might Not Need an Effect

Official documentation:


21. Running the Application

Development server:

npm run dev

Production validation:

npm run build

Production preview:

npm run preview

22. Complete Rendering Flow

main.tsx
renders App
App
stores selectedId state
Sidebar
receives selectedId and setSelectedId
User clicks a button
setSelectedId updates state
React re-renders
PageContent
receives selectedItem
UI updates automatically

This is the React mental model.


Technical Summary

ConceptExplanation
useStateStores selected navigation item
map()Converts data into navigation buttons
Derived dataselectedItem calculated from state
Fluent UI ButtonEnterprise navigation component
FlexboxSidebar + content layout
TypeScript interfacePredictable navigation structure
.tsData/types only
.tsxJSX/React components
Conditional renderingActive menu highlighting
PropsSend selected item into PageContent

Concept Table

ConceptFilePurpose
Navigation modelNavigationItem.tsDefines navigation structure
Navigation datanavigationItems.tsStores sidebar items
Sidebar renderingSidebar.tsxRenders menu buttons
Main contentPageContent.tsxShows selected section
State ownershipApp.tsxControls selected navigation
React rootmain.tsxConnects React to HTML
Global CSSindex.cssRemoves default browser margin

Official Documentation

TopicDocumentation
React Learnhttps://react.dev/learn
Rendering Listshttps://react.dev/learn/rendering-lists
State: A Component’s Memoryhttps://react.dev/learn/state-a-components-memory
Passing Props to a Componenthttps://react.dev/learn/passing-props-to-a-component
Choosing the State Structurehttps://react.dev/learn/choosing-the-state-structure
You Might Not Need an Effecthttps://react.dev/learn/you-might-not-need-an-effect
Fluent UI React Componentshttps://developer.microsoft.com/en-us/fluentui#/controls/web
Fluent UI Buttonhttps://developer.microsoft.com/en-us/fluentui#/controls/web/button
Vite Guidehttps://vite.dev/guide/
TypeScript Docshttps://www.typescriptlang.org/docs/

Final Architectural Insight

This app may appear visually simple, but architecturally it introduces one of the most common enterprise React patterns:

Sidebar Navigation
→ Selected State
→ Derived Content
→ Enterprise Layout

This exact structure later evolves into:

  • admin dashboards
  • CRM systems
  • SharePoint portals
  • ERP systems
  • analytics platforms
  • Microsoft-style enterprise applications

Because in React:

Navigation is state.
UI derives from state.
React renders the result.

Current Project Progress

BlockAppNameStatus
Block 341Microsoft Style LoginCompleted
Block 342Corporate FormCompleted
Block 343Tabs NavigationCompleted
Block 344Dialog ManagerCompleted
Block 345Executive DashboardCompleted
Block 346DataGrid CatalogCompleted
Block 347Enterprise User ListCompleted
Block 348Navigable SidebarCurrent
Block 349Corporate HeaderNext

Edvaldo Guimrães Filho Avatar

Published by