Content micro-frontend for the FitTrack fitness-tracking platform. Exposes the user-facing feature pages — Activities, Nutrition, Dashboard, and the FitoAI streaming chat assistant — via Webpack 5 Module Federation, so the host shell can mount them at runtime.
Built with React 19, TypeScript, Tailwind CSS, shadcn/ui, TanStack Query, Zustand, and react-router v7.
This package is one piece of a larger system:
┌──────────────────────┐ ┌────────────────────────┐
│ FitTrack Host UI │ ──► │ ContentMF (this repo) │
│ (shell, auth, nav) │ │ remoteEntry.js @ 3001 │
└──────────────────────┘ └───────────┬────────────┘
│
┌───────────────────┴───────────────────┐
▼ ▼
┌────────────────────┐ ┌────────────────────────┐
│ Activity / Nutri. │ │ FitoAI service (SSE) │
│ service @ :8072 │ │ Spring AI @ :8073 │
└────────────────────┘ └────────────────────────┘
- Module Federation — exposes
./ContentMF(mountingsrc/App.tsx) under remote nameContentMFfromremoteEntry.js.reactandreact-domare shared singletons (^19.2.0, eager). - Routing — when a
currentPathprop is passed (host-mounted mode) the app usesMemoryRouter; standalone mode usesBrowserRouter. - Auth — bearer token is read from
localStorage.authToken, set by the host shell. Routes are unguarded inside this MFE; the shell handles login. - Data — TanStack Query for caching/fetching, Axios for REST, native
fetch+ReadableStreamfor SSE chat streaming. - State — Zustand
useUserStoreholds the activeuserIdinjected by the host.
| Route | Component | Backend |
|---|---|---|
/dashboard |
DashboardPage |
BASE_API_URL/activities |
/activities |
ActivityPage |
BASE_API_URL/activities |
/nutrition |
NutritionPage |
BASE_API_URL/nutrition |
/fitoai |
FitoAIPage |
FITOAI_API_URL/chat (SSE) |
/analytics |
placeholder | — |
/goals |
placeholder | — |
/profile |
placeholder | — |
- Node.js 20+
- npm (project ships a
package-lock.jsonworkflow; pnpm/yarn also work) - The FitTrack backend services running locally:
- Activity / Nutrition gateway on
http://localhost:8072 - FitoAI (Spring AI) on
http://localhost:8073
- Activity / Nutrition gateway on
npm install
# Webpack dev server with Module Federation (default — what the host expects)
npm run dev # serves remoteEntry.js at http://localhost:3001
# Standalone Vite dev server (faster HMR, no federation)
npm run dev:viteBuild:
npm run build # webpack production build → dist/
npm run build:vite # tsc + vite build (standalone)Lint:
npm run lintAPI endpoints currently live in src/constants/appConstants.ts:
export const BASE_API_URL = "http://localhost:8072/api";
export const FITOAI_API_URL = "http://localhost:8073/api/ai";When deploying, replace these with environment-driven values (e.g. import.meta.env.VITE_API_BASE_URL) before publishing the build.
// host webpack.config.js
new ModuleFederationPlugin({
name: "Host",
remotes: {
ContentMF: "ContentMF@http://localhost:3001/remoteEntry.js",
},
shared: {
react: { singleton: true, requiredVersion: "^19.2.0", eager: true },
"react-dom": { singleton: true, requiredVersion: "^19.2.0", eager: true },
},
});// host usage
const ContentMF = React.lazy(() => import("ContentMF/ContentMF"));
<Suspense fallback={<Loading />}>
<ContentMF currentPath={location.pathname} userId={user.id} />
</Suspense>App props:
| Prop | Type | Notes |
|---|---|---|
currentPath |
string | undefined |
If provided, mounts under MemoryRouter. Omit for standalone use. |
userId |
number | undefined |
Forwarded to all feature pages for scoping API requests. |
src/
├── App.tsx # routes + providers, MFE entry
├── bootstrap.tsx # standalone bootstrap (createRoot)
├── main.tsx # async import of bootstrap (MF requirement)
├── components/ui/ # shadcn/ui primitives
├── constants/ # API URLs, route paths
├── pages/
│ ├── Activities/
│ ├── Dashboard/
│ ├── Nutrition/
│ └── FitoAI/ # SSE-streamed chat UI
├── services/
│ ├── api/ # axios + fetch clients per domain
│ └── hooks/ # TanStack Query hooks
├── store/userStore.ts # Zustand user state
├── types/ # domain models + request DTOs
└── utils/queryClient.ts # shared QueryClient
- React 19 + TypeScript 5.9 + React Compiler (Babel plugin)
- Webpack 5 with Module Federation for runtime composition; Vite 7 for standalone dev
- Tailwind CSS 3 + shadcn/ui (Radix primitives) +
lucide-react - TanStack Query 5 for server state, Zustand 5 for client state
- Axios for REST, native
fetch+ SSE for streaming chat
MIT — see LICENSE.