UI: Migrate from React to Nuxt 4 for consistency with Customable stack #333

Closed
opened 2026-03-02 12:34:47 +00:00 by jack · 0 comments
Owner

Problem

Inkonsistenter Tech-Stack über Customable-Projekte:

Projekt Frontend
erp-platform (ACP, CCP, Shop) Nuxt 4 + Vue 3
ui-kit Vue 3 Components
claude-mem React 19 + Vite

Nachteile:

  • Keine UI-Kit-Komponenten nutzbar (Vue ≠ React)
  • Zwei Frontend-Technologien parallel maintainen
  • Kein Code-Sharing zwischen Projekten
  • Inkonsistente DX für Entwickler

Gewünschte Änderung

Migration: React → Nuxt 4

- "react": "^19.2.3"
- "react-dom": "^19.2.3"
- "@vitejs/plugin-react": "^5.1.2"
+ "nuxt": "^3.15.0"
+ "@customable/ui-kit": "^1.x.x"

Vorteile

  • UI-Kit nutzbar - Alle Komponenten out-of-the-box
  • SSR/SSG - Optional möglich (aktuell nur SPA)
  • File-based Routing - Wie erp-platform
  • Auto-Imports - Weniger Boilerplate
  • Konsistenter Stack - Ein Framework für alle Projekte
  • Code-Sharing - Composables/Utils wiederverwendbar

Migration-Strategie

Phase 1: Nuxt Setup

# packages/ui/
pnpm remove react react-dom @vitejs/plugin-react
pnpm add nuxt @customable/ui-kit
// nuxt.config.ts
export default defineNuxtConfig({
  ssr: false, // SPA-Mode (wie aktuell)
  modules: ['@customable/ui-kit/nuxt'],
  devServer: { port: 5173 },
  app: {
    baseURL: '/'
  }
});

Phase 2: Komponenten migrieren

React → Vue Conversion:

// React (vorher)
import { useState } from 'react';

export function Sidebar({ currentView, onNavigate }) {
  const [isOpen, setIsOpen] = useState(false);
  
  return (
    <aside className="sidebar">
      <button onClick={() => onNavigate('dashboard')}>
        Dashboard
      </button>
    </aside>
  );
}
<!-- Vue (nachher) -->
<script setup lang="ts">
const props = defineProps<{
  currentView: string;
}>();

const emit = defineEmits<{
  navigate: [view: string];
}>();

const isOpen = ref(false);
</script>

<template>
  <aside class="sidebar">
    <button @click="emit('navigate', 'dashboard')">
      Dashboard
    </button>
  </aside>
</template>

Phase 3: File-Structure

packages/ui/
├── nuxt.config.ts
├── app.vue
├── pages/
│   ├── index.vue           # Dashboard
│   ├── sessions.vue
│   ├── search.vue
│   └── settings.vue
├── components/
│   ├── Sidebar.vue
│   ├── StatusBar.vue
│   └── Console.vue
├── composables/
│   ├── useApi.ts
│   └── useWebSocket.ts
└── public/
    └── favicon.ico

Phase 4: Routing

// React Router (vorher)
const [currentView, setCurrentView] = useState('dashboard');

// Nuxt Router (nachher)
const router = useRouter();
router.push('/sessions');

Phase 5: State-Management

// React Context (vorher)
const [sessions, setSessions] = useState([]);

// Nuxt State (nachher)
const sessions = useState('sessions', () => []);
// Oder Pinia Store
export const useSessionStore = defineStore('sessions', () => {
  const sessions = ref([]);
  return { sessions };
});

Chart.js Integration (bleibt)

<script setup>
import { Line } from 'vue-chartjs';
import { Chart as ChartJS, LineElement, ... } from 'chart.js';

ChartJS.register(LineElement, ...);
</script>

<template>
  <Line :data="chartData" :options="chartOptions" />
</template>

API-Client (bleibt gleich)

// composables/useApi.ts
export function useApi() {
  const baseURL = 'http://localhost:37777';
  
  async function getSessions() {
    return await ('/api/sessions', { baseURL });
  }
  
  return { getSessions };
}

Build-Output

# SPA-Build
pnpm build
# → .output/public/ (wie aktuell dist/)

# SSR/SSG (optional später)
pnpm build --ssr
# → .output/server/

Zeitaufwand

Schätzung:

  • Setup & Config: 2h
  • Komponenten migrieren: 12h (10 Komponenten × 1-2h)
  • Routing: 2h
  • State-Management: 3h
  • Testing: 4h

Total: ~23h

Alternative: Behalten als React

Falls Migration zu aufwändig:

  • React-Wrapper für Vue-Komponenten (z.B. via Veaury)
  • Trotzdem inkonsistent

Acceptance Criteria

  • Nuxt 4 Setup funktioniert
  • Alle Pages migriert (Dashboard, Sessions, etc.)
  • Alle Components migriert
  • UI-Kit Components integriert
  • Routing funktioniert
  • API-Calls funktionieren
  • Build funktioniert (pnpm build)
  • Visuell identisch
  • Keine React-Dependencies mehr

Priority

Low - Wichtig für Konsistenz, aber nicht dringend.

  • Depends on: #327 (UI-Kit Migration) - sollte zusammen gemacht werden
## Problem **Inkonsistenter Tech-Stack** über Customable-Projekte: | Projekt | Frontend | |---------|----------| | erp-platform (ACP, CCP, Shop) | ✅ **Nuxt 4** + Vue 3 | | ui-kit | ✅ **Vue 3** Components | | **claude-mem** | ❌ **React 19** + Vite | **Nachteile:** - Keine UI-Kit-Komponenten nutzbar (Vue ≠ React) - Zwei Frontend-Technologien parallel maintainen - Kein Code-Sharing zwischen Projekten - Inkonsistente DX für Entwickler ## Gewünschte Änderung **Migration: React → Nuxt 4** ```diff - "react": "^19.2.3" - "react-dom": "^19.2.3" - "@vitejs/plugin-react": "^5.1.2" + "nuxt": "^3.15.0" + "@customable/ui-kit": "^1.x.x" ``` ## Vorteile - ✅ **UI-Kit nutzbar** - Alle Komponenten out-of-the-box - ✅ **SSR/SSG** - Optional möglich (aktuell nur SPA) - ✅ **File-based Routing** - Wie erp-platform - ✅ **Auto-Imports** - Weniger Boilerplate - ✅ **Konsistenter Stack** - Ein Framework für alle Projekte - ✅ **Code-Sharing** - Composables/Utils wiederverwendbar ## Migration-Strategie ### Phase 1: Nuxt Setup ```bash # packages/ui/ pnpm remove react react-dom @vitejs/plugin-react pnpm add nuxt @customable/ui-kit ``` ```typescript // nuxt.config.ts export default defineNuxtConfig({ ssr: false, // SPA-Mode (wie aktuell) modules: ['@customable/ui-kit/nuxt'], devServer: { port: 5173 }, app: { baseURL: '/' } }); ``` ### Phase 2: Komponenten migrieren **React → Vue Conversion:** ```tsx // React (vorher) import { useState } from 'react'; export function Sidebar({ currentView, onNavigate }) { const [isOpen, setIsOpen] = useState(false); return ( <aside className="sidebar"> <button onClick={() => onNavigate('dashboard')}> Dashboard </button> </aside> ); } ``` ```vue <!-- Vue (nachher) --> <script setup lang="ts"> const props = defineProps<{ currentView: string; }>(); const emit = defineEmits<{ navigate: [view: string]; }>(); const isOpen = ref(false); </script> <template> <aside class="sidebar"> <button @click="emit('navigate', 'dashboard')"> Dashboard </button> </aside> </template> ``` ### Phase 3: File-Structure ``` packages/ui/ ├── nuxt.config.ts ├── app.vue ├── pages/ │ ├── index.vue # Dashboard │ ├── sessions.vue │ ├── search.vue │ └── settings.vue ├── components/ │ ├── Sidebar.vue │ ├── StatusBar.vue │ └── Console.vue ├── composables/ │ ├── useApi.ts │ └── useWebSocket.ts └── public/ └── favicon.ico ``` ### Phase 4: Routing ```typescript // React Router (vorher) const [currentView, setCurrentView] = useState('dashboard'); // Nuxt Router (nachher) const router = useRouter(); router.push('/sessions'); ``` ### Phase 5: State-Management ```typescript // React Context (vorher) const [sessions, setSessions] = useState([]); // Nuxt State (nachher) const sessions = useState('sessions', () => []); // Oder Pinia Store export const useSessionStore = defineStore('sessions', () => { const sessions = ref([]); return { sessions }; }); ``` ## Chart.js Integration (bleibt) ```vue <script setup> import { Line } from 'vue-chartjs'; import { Chart as ChartJS, LineElement, ... } from 'chart.js'; ChartJS.register(LineElement, ...); </script> <template> <Line :data="chartData" :options="chartOptions" /> </template> ``` ## API-Client (bleibt gleich) ```typescript // composables/useApi.ts export function useApi() { const baseURL = 'http://localhost:37777'; async function getSessions() { return await ('/api/sessions', { baseURL }); } return { getSessions }; } ``` ## Build-Output ```bash # SPA-Build pnpm build # → .output/public/ (wie aktuell dist/) # SSR/SSG (optional später) pnpm build --ssr # → .output/server/ ``` ## Zeitaufwand **Schätzung:** - Setup & Config: 2h - Komponenten migrieren: 12h (10 Komponenten × 1-2h) - Routing: 2h - State-Management: 3h - Testing: 4h **Total: ~23h** ## Alternative: Behalten als React Falls Migration zu aufwändig: - React-Wrapper für Vue-Komponenten (z.B. via Veaury) - Trotzdem inkonsistent ## Acceptance Criteria - [x] Nuxt 4 Setup funktioniert - [x] Alle Pages migriert (Dashboard, Sessions, etc.) - [x] Alle Components migriert - [x] UI-Kit Components integriert - [x] Routing funktioniert - [x] API-Calls funktionieren - [x] Build funktioniert (`pnpm build`) - [x] Visuell identisch - [x] Keine React-Dependencies mehr ## Priority **Low** - Wichtig für Konsistenz, aber nicht dringend. ## Related - Depends on: #327 (UI-Kit Migration) - sollte zusammen gemacht werden
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
customable/claude-mem#333
No description provided.