Skip to main content

capacitor-vite-nextjs-backend

Setup and patterns for a Vite + React frontend with Capacitor and Ionic React, plus a separate Next.js backend in a monorepo. Use when creating or modifying a Capacitor mobile app with a Vite frontend and Next.js API, or when adding Capacitor to an existing Vite app with a Next.js backend.

Aller à l'installation

Informations de source

Dépôt
pmarashian/cursor-agent-skills
Dernière activité de la source
16 février 2026 à 13:48
Langue détectée de SKILL.md
anglais
Étoiles
2
Forks
1

Options d'installation

Le prompt qui vérifie d'abord la source est sélectionné par défaut. Vous pouvez passer à une commande directe ou télécharger une copie locale.

Vérifiez les fichiers source

Lisez SKILL.md et les fichiers associés affichés par SkillsMP avant de décider de l'installer.

Affichage de SKILL.md

SKILL.md
Instructions source · Aperçu en lecture seule
name
capacitor-vite-nextjs-backend
description
Setup and patterns for a Vite + React frontend with Capacitor and Ionic React, plus a separate Next.js backend in a monorepo. Use when creating or modifying a Capacitor mobile app with a Vite frontend and Next.js API, or when adding Capacitor to an existing Vite app with a Next.js backend.
# Capacitor + Vite Frontend + Next.js Backend ## Purpose This skill provides a comprehensive guide for setting up a Vite + React frontend with Capacitor for native mobile support and Ionic React for UI components, paired with a separate Next.js backend API. This architecture separates concerns: the frontend is a pure SPA built with Vite, and the backend is a Next.js API server. ## When to Use Use this skill when: - Setting up a new Capacitor mobile app with Vite + React frontend and Next.js backend - Adding Capacitor to an existing Vite + React app that calls a Next.js API - Configuring API base URLs for Capacitor apps (critical: native apps can't use localhost) - Understanding the monorepo structure for frontend/backend separation - Troubleshooting Capacitor build or sync issues with Vite ## Architecture Overview ### Monorepo Structure ``` your-project/ ├── frontend/ # Vite + React + Capacitor + Ionic │ ├── src/ │ │ ├── main.tsx # Entry point with Ionic setup │ │ ├── App.tsx # Root component with routing │ │ ├── lib/ │ │ │ └── apiConfig.ts # API base URL configuration │ │ └── ... │ ├── capacitor.config.ts │ ├── vite.config.mts │ ├── package.json │ └── index.html ├── backend/ # Next.js API │ ├── src/ │ │ └── app/ │ │ └── api/ # API routes │ └── package.json └── package.json # Optional root package.json ``` ### Key Concepts - **Vite Frontend**: Pure SPA that builds to static `dist/` directory - **Capacitor Integration**: Wraps the static Vite build (`frontend/dist`) into native iOS/Android apps - **Next.js Backend**: Separate API server (runs on port 3000, frontend on 3001) - **API Configuration**: Critical distinction - native apps must use deployed backend URL, not localhost - **Ionic React**: Mobile-optimized UI components that work on web and native ## Core Setup Instructions ### Step 1: Create Vite Frontend ```bash npm create vite@latest frontend -- --template react-ts cd frontend npm install ``` ### Step 2: Install Capacitor and Ionic Dependencies ```bash # Capacitor Core npm install @capacitor/core @capacitor/cli @capacitor/android @capacitor/ios # Ionic React npm install @ionic/react ionicons # Optional but recommended npm install @capacitor/preferences ``` ### Step 3: Initialize Capacitor ```bash npx cap init ``` When prompted: - **App name**: YourAppName - **App ID**: com.yourcompany.yourapp (use reverse domain notation) - **Web dir**: `dist` (Vite outputs to `dist/` by default) This creates `capacitor.config.ts` in the `frontend/` directory. ### Step 4: Configure Capacitor Update `frontend/capacitor.config.ts`: ```typescript import { CapacitorConfig } from "@capacitor/cli"; const config: CapacitorConfig = { appId: "com.yourcompany.yourapp", appName: "YourAppName", webDir: "dist", bundledWebRuntime: false, }; export default config; ``` **Important**: `webDir` must be `"dist"` to match Vite's output directory. `bundledWebRuntime: false` is recommended for better performance. ### Step 5: Configure Vite Update `frontend/vite.config.mts`: ```typescript import { defineConfig } from 'vite'; import react from '@vitejs/plugin-react'; export default defineConfig({ plugins: [react()], server: { host: true, // Allows access from network (useful for testing on devices) }, }); ``` No special Capacitor-specific configuration needed - Vite always produces static assets. ### Step 6: Create HTML Entry Point Create `frontend/index.html`: ```html <!doctype html> <html lang="en"> <head> <meta charset="utf-8" /> <title>Your App Name</title> <base href="/" /> <meta name="color-scheme" content="light dark" /> <meta name="viewport" content="viewport-fit=cover, width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no" /> <meta name="format-detection" content="telephone=no" /> <meta name="msapplication-tap-highlight" content="no" /> </head> <body> <div id="root"></div> <script type="module" src="/src/main.tsx"></script> </body> </html> ``` **Key viewport settings**: `viewport-fit=cover` ensures content extends under notches/safe areas on mobile devices. ### Step 7: Create Main Entry Point with Ionic Setup Create `frontend/src/main.tsx`: ```typescript import React from 'react'; import { createRoot } from 'react-dom/client'; import { setupIonicReact } from '@ionic/react'; import { Capacitor } from '@capacitor/core'; import App from './App'; /* Core CSS required for Ionic components to work properly */ import '@ionic/react/css/core.css'; /* Basic CSS for apps built with Ionic */ import '@ionic/react/css/normalize.css'; import '@ionic/react/css/structure.css'; import '@ionic/react/css/typography.css'; /* Optional CSS utils */ import '@ionic/react/css/padding.css'; import '@ionic/react/css/float-elements.css'; import '@ionic/react/css/text-alignment.css'; import '@ionic/react/css/text-transformation.css'; import '@ionic/react/css/flex-utils.css'; import '@ionic/react/css/display.css'; /* Theme variables */ import './theme/variables.css'; setupIonicReact(); // Optional: Platform detection for logging/config const platform = Capacitor.isNativePlatform() ? 'native' : 'web'; const platformName = Capacitor.getPlatform(); console.log('Platform:', platform, platformName); const container = document.getElementById('root'); const root = createRoot(container!); root.render( <React.StrictMode> <App /> </React.StrictMode> ); ``` **Critical**: `setupIonicReact()` must be called before rendering any Ionic components. ### Step 8: Create App Component with Routing Create `frontend/src/App.tsx`: ```typescript import { IonApp } from '@ionic/react'; import { BrowserRouter as Router, Routes, Route, Navigate } from 'react-router-dom'; import Home from './pages/Home'; import Settings from './pages/Settings'; const App: React.FC = () => { return ( <IonApp style={{ margin: 0, padding: 0, height: '100vh', minHeight: '100vh', display: 'flex', flexDirection: 'column' }}> <Router> <Routes> <Route path="/" element={<Navigate to="/home" replace />} /> <Route path="/home" element={<Home />} /> <Route path="/settings" element={<Settings />} /> </Routes> </Router> </IonApp> ); }; export default App; ``` **Key points**: - Wrap entire app in `<IonApp>` (required for Ionic components) - Use `react-router-dom` for client-side routing (not file-based like Next.js) - All routes defined in one place ### Step 9: Create API Configuration (Critical) Create `frontend/src/lib/apiConfig.ts`: ```typescript import { Capacitor } from "@capacitor/core"; const DEFAULT_DEV = "http://localhost:3000"; const DEFAULT_PROD = "https://your-api.com"; /** * Get the API base URL for making API calls. * * CRITICAL: In Capacitor native apps (iOS/Android), always use deployed backend. * Localhost on device is the device itself, not your development machine. */ export function getApiBaseUrl(): string { const fromEnv = import.meta.env.VITE_API_URL; // Environment variable override (highest priority) if (fromEnv && typeof fromEnv === "string") { return fromEnv.replace(/\/$/, ""); } // Native platform: always use production/deployed URL if (Capacitor.isNativePlatform()) { const prodUrl = import.meta.env.VITE_PROD_API_URL ?? DEFAULT_PROD; return (typeof prodUrl === "string" ? prodUrl : DEFAULT_PROD).replace(/\/$/, ""); } // Web platform: use localhost in dev, production in prod const apiUrl = import.meta.env.DEV ? DEFAULT_DEV : DEFAULT_PROD; return apiUrl; } /** * Get the full API URL for a given endpoint. */ export function getApiUrl(endpoint: string): string { const base = getApiBaseUrl(); const path = endpoint.startsWith("/") ? endpoint : `/${endpoint}`; return `${base}${path}`; } ``` **Critical rule**: Native apps (iOS/Android) **must** use a deployed backend URL. Localhost on a device refers to the device itself, not your development machine. ### Step 10: Configure TypeScript Update `frontend/tsconfig.json`: ```json { "compilerOptions": { "target": "ES2020", "useDefineForClassFields": true, "lib": ["ES2020", "DOM", "DOM.Iterable"], "module": "ESNext", "skipLibCheck": true, "moduleResolution": "bundler", "allowImportingTsExtensions": true, "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, "jsx": "react-jsx", "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true }, "include": ["src"], "references": [{ "path": "./tsconfig.node.json" }] } ``` **Key differences from Next.js**: Uses `jsx: "react-jsx"` (not `"preserve"`), no Next.js TypeScript plugin, `moduleResolution: "bundler"` for Vite. ### Step 11: Update Package Scripts Update `frontend/package.json` scripts: ```json { "scripts": { "dev": "vite --port 3001", "build": "vite build", "preview": "vite preview", "cap:sync": "npm run build && npx cap sync", "cap:open:ios": "npx cap open ios", "cap:open:android": "npx cap open android", "cap:run:ios": "npx cap run ios" } } ``` **Important**: `cap:sync` runs `npm run build` first to ensure `dist/` exists before syncing to native platforms. ### Step 12: Add Native Platforms ```bash # iOS npx cap add ios npx cap sync # Android npx cap add android npx cap sync ``` All Capacitor commands run from the `frontend/` directory. ## Environment Variables Create `frontend/.env` files: **`.env.development`**: ``` VITE_API_URL=http://localhost:3000 VITE_PROD_API_URL=https://your-api.com ``` **`.env.production`**: ``` VITE_API_URL=https://your-api.com VITE_PROD_API_URL=https://your-api.com ``` **Important**: Use `VITE_` prefix for all environment variables that should be accessible in the frontend code. Variables without this prefix are not exposed to the client. ## Backend Setup (Next.js) The backend is a standard Next.js API. Key points: 1. **CORS Configuration**: Backend must allow requests from: - `http://localhost:3001` (web dev) - Capacitor's origin (varies by platform) - Your production frontend domain 2. **API Routes**: Create routes in `backend/src/app/api/`: ```typescript // backend/src/app/api/example/route.ts export async function GET() { return Response.json({ message: 'Hello from Next.js API' }); } ``` 3. **Port**: Backend typically runs on port 3000, frontend on 3001. ## Optional Enhancements ### Theme Variables Create `frontend/src/theme/variables.css`: ```css :root { --ion-color-primary: #3880ff; --ion-color-primary-rgb: 56, 128, 255; --ion-color-primary-contrast: #ffffff; --ion-color-primary-shade: #3171e0; --ion-color-primary-tint: #4c8dff; } @media (prefers-color-scheme: dark) { :root { --ion-color-primary: #428cff; /* ... other dark mode variables ... */ } } ``` ### Tab Bar Navigation Example tab bar that only shows on certain routes:
Voir sur GitHub
Ce SKILL.md est tres volumineux, SkillsMP affiche donc ici seulement la premiere section. Voir sur GitHub