framework-to-capacitor

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Framework to Capacitor Integration

Web框架与Capacitor集成

Comprehensive guide for integrating web frameworks with Capacitor to build mobile apps.
本指南详细介绍如何将Web框架与Capacitor集成以构建移动应用。

When to Use This Skill

何时使用本指南

  • Converting a Next.js app to a mobile app
  • Integrating React, Vue, Angular, or Svelte with Capacitor
  • Configuring static exports for Capacitor
  • Setting up routing for mobile apps
  • Optimizing framework builds for native platforms
  • 将Next.js应用转换为移动应用
  • 集成React、Vue、Angular或Svelte与Capacitor
  • 为Capacitor配置静态导出
  • 为移动应用设置路由
  • 针对原生平台优化框架构建产物

Framework Support Matrix

框架支持矩阵

FrameworkStatic ExportSSR SupportRecommended Approach
Next.js✅ Yes❌ NoStatic export (output: 'export')
React✅ YesN/ACreate React App or Vite
Vue✅ Yes❌ NoVite or Vue CLI
Angular✅ Yes❌ NoAngular CLI
Svelte✅ Yes❌ NoSvelteKit with adapter-static
Remix✅ Yes❌ NoSPA mode
Solid✅ Yes❌ NoVite
Qwik✅ Yes❌ NoStatic site mode
CRITICAL: Capacitor requires static HTML/CSS/JS files. SSR (Server-Side Rendering) does not work in native apps.

框架静态导出SSR支持推荐方案
Next.js✅ 支持❌ 不支持静态导出(配置:output: 'export')
React✅ 支持不适用Create React App 或 Vite
Vue✅ 支持❌ 不支持Vite 或 Vue CLI
Angular✅ 支持❌ 不支持Angular CLI
Svelte✅ 支持❌ 不支持SvelteKit + adapter-static
Remix✅ 支持❌ 不支持SPA模式
Solid✅ 支持❌ 不支持Vite
Qwik✅ 支持❌ 不支持静态站点模式
重要提示:Capacitor需要静态HTML/CSS/JS文件。SSR(服务器端渲染)在原生应用中无法工作。

Next.js + Capacitor

Next.js + Capacitor

Next.js is popular for React apps. Capacitor requires static export.
Next.js是热门的React应用框架。Capacitor要求使用静态导出。

Step 1: Create or Update next.config.js

步骤1:创建或更新next.config.js

For Next.js 13+ (App Router):
javascript
// next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
  output: 'export',
  images: {
    unoptimized: true, // Required for static export
  },
  trailingSlash: true, // Helps with routing on mobile
};

module.exports = nextConfig;
For Next.js 12 (Pages Router):
javascript
// next.config.js
module.exports = {
  output: 'export',
  images: {
    unoptimized: true,
  },
  trailingSlash: true,
};
适用于Next.js 13+(App Router):
javascript
// next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
  output: 'export',
  images: {
    unoptimized: true, // 静态导出必填
  },
  trailingSlash: true, // 有助于移动端路由
};

module.exports = nextConfig;
适用于Next.js 12(Pages Router):
javascript
// next.config.js
module.exports = {
  output: 'export',
  images: {
    unoptimized: true,
  },
  trailingSlash: true,
};

Step 2: Build Static Files

步骤2:构建静态文件

bash
bun run build
This creates an
out/
directory with static files.
bash
bun run build
此命令会创建包含静态文件的
out/
目录。

Step 3: Install Capacitor

步骤3:安装Capacitor

bash
bun add @capacitor/core @capacitor/cli
bunx cap init
Configuration:
  • App name: Your app name
  • App ID: com.company.app
  • Web directory:
    out
    (Next.js static export output)
bash
bun add @capacitor/core @capacitor/cli
bunx cap init
配置项:
  • App name:你的应用名称
  • App ID:com.company.app
  • Web directory
    out
    (Next.js静态导出的输出目录)

Step 4: Configure Capacitor

步骤4:配置Capacitor

Create capacitor.config.ts:
typescript
import type { CapacitorConfig } from '@capacitor/cli';

const config: CapacitorConfig = {
  appId: 'com.company.app',
  appName: 'My App',
  webDir: 'out', // Next.js static export directory
  server: {
    androidScheme: 'https',
  },
};

export default config;
创建capacitor.config.ts:
typescript
import type { CapacitorConfig } from '@capacitor/cli';

const config: CapacitorConfig = {
  appId: 'com.company.app',
  appName: 'My App',
  webDir: 'out', // Next.js静态导出目录
  server: {
    androidScheme: 'https',
  },
};

export default config;

Step 5: Add Platforms

步骤5:添加平台

bash
bun add @capacitor/ios @capacitor/android
bunx cap add ios
bunx cap add android
bash
bun add @capacitor/ios @capacitor/android
bunx cap add ios
bunx cap add android

Step 6: Build and Sync

步骤6:构建与同步

bash
undefined
bash
undefined

Build Next.js

构建Next.js应用

bun run build
bun run build

Sync with native projects

与原生项目同步

bunx cap sync
undefined
bunx cap sync
undefined

Step 7: Run on Device

步骤7:在设备上运行

iOS:
bash
bunx cap open ios
iOS:
bash
bunx cap open ios

Build and run in Xcode

在Xcode中构建并运行


**Android:**
```bash
bunx cap open android

**Android:**
```bash
bunx cap open android

Build and run in Android Studio

在Android Studio中构建并运行

undefined
undefined

Next.js Routing Considerations

Next.js路由注意事项

Use hash routing for complex apps:
typescript
// next.config.js
const nextConfig = {
  output: 'export',
  basePath: '',
  assetPrefix: '',
};
Or use Next.js's built-in routing (works with
trailingSlash: true
).
复杂应用建议使用哈希路由:
typescript
// next.config.js
const nextConfig = {
  output: 'export',
  basePath: '',
  assetPrefix: '',
};
或使用Next.js内置路由(需配合
trailingSlash: true
使用)。

Next.js Image Optimization

Next.js图片优化

next/image doesn't work with static export. Use alternatives:
Option 1: Use standard img tag
jsx
// Instead of next/image
<img src="/images/photo.jpg" alt="Photo" />
Option 2: Use a custom Image component
tsx
// components/CapacitorImage.tsx
import { Capacitor } from '@capacitor/core';

export const CapacitorImage = ({ src, alt, ...props }) => {
  const isNative = Capacitor.isNativePlatform();
  const imageSrc = isNative ? src : src;
  
  return <img src={imageSrc} alt={alt} {...props} />;
};
next/image在静态导出中无法工作,可使用替代方案:
方案1:使用标准img标签
jsx
// 替代next/image
<img src="/images/photo.jpg" alt="Photo" />
方案2:使用自定义Image组件
tsx
// components/CapacitorImage.tsx
import { Capacitor } from '@capacitor/core';

export const CapacitorImage = ({ src, alt, ...props }) => {
  const isNative = Capacitor.isNativePlatform();
  const imageSrc = isNative ? src : src;
  
  return <img src={imageSrc} alt={alt} {...props} />;
};

Next.js API Routes

Next.js API路由

API routes don't work in static export. Use alternatives:
  1. External API: Call a separate backend
  2. Capacitor plugins: Use native features
  3. Local storage: Use
    @capacitor/preferences
typescript
import { Preferences } from '@capacitor/preferences';

// Save data
await Preferences.set({
  key: 'user',
  value: JSON.stringify(userData),
});

// Load data
const { value } = await Preferences.get({ key: 'user' });
const userData = JSON.parse(value || '{}');
API路由在静态导出中无法工作,可使用以下替代方案:
  1. 外部API:调用独立的后端服务
  2. Capacitor插件:使用原生功能
  3. 本地存储:使用
    @capacitor/preferences
typescript
import { Preferences } from '@capacitor/preferences';

// 保存数据
await Preferences.set({
  key: 'user',
  value: JSON.stringify(userData),
});

// 加载数据
const { value } = await Preferences.get({ key: 'user' });
const userData = JSON.parse(value || '{}');

Next.js Middleware

Next.js中间件

Middleware doesn't work in static export. Handle logic client-side:
typescript
// In your React components
import { useEffect } from 'react';
import { useRouter } from 'next/router';

export default function ProtectedPage() {
  const router = useRouter();

  useEffect(() => {
    const checkAuth = async () => {
      const { value } = await Preferences.get({ key: 'token' });
      if (!value) {
        router.push('/login');
      }
    };
    checkAuth();
  }, []);

  return <div>Protected content</div>;
}
中间件在静态导出中无法工作,需在客户端处理逻辑:
typescript
// 在React组件中
import { useEffect } from 'react';
import { useRouter } from 'next/router';

export default function ProtectedPage() {
  const router = useRouter();

  useEffect(() => {
    const checkAuth = async () => {
      const { value } = await Preferences.get({ key: 'token' });
      if (!value) {
        router.push('/login');
      }
    };
    checkAuth();
  }, []);

  return <div>受保护内容</div>;
}

Complete Next.js + Capacitor Example

Next.js + Capacitor完整示例

package.json:
json
{
  "name": "my-capacitor-app",
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "build:mobile": "next build && cap sync",
    "ios": "cap open ios",
    "android": "cap open android"
  },
  "dependencies": {
    "next": "^14.0.0",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "@capacitor/core": "^6.0.0",
    "@capacitor/ios": "^6.0.0",
    "@capacitor/android": "^6.0.0",
    "@capacitor/camera": "^6.0.0"
  },
  "devDependencies": {
    "@capacitor/cli": "^6.0.0",
    "typescript": "^5.0.0"
  }
}

package.json:
json
{
  "name": "my-capacitor-app",
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "build:mobile": "next build && cap sync",
    "ios": "cap open ios",
    "android": "cap open android"
  },
  "dependencies": {
    "next": "^14.0.0",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "@capacitor/core": "^6.0.0",
    "@capacitor/ios": "^6.0.0",
    "@capacitor/android": "^6.0.0",
    "@capacitor/camera": "^6.0.0"
  },
  "devDependencies": {
    "@capacitor/cli": "^6.0.0",
    "typescript": "^5.0.0"
  }
}

React + Capacitor

React + Capacitor

React works great with Capacitor using Vite or Create React App.
React可通过Vite或Create React App很好地与Capacitor集成。

Option 1: Vite (Recommended)

方案1:Vite(推荐)

Create new project:
bash
bun create vite my-app --template react-ts
cd my-app
bun install
Install Capacitor:
bash
bun add @capacitor/core @capacitor/cli
bunx cap init
Configure vite.config.ts:
typescript
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';

export default defineConfig({
  plugins: [react()],
  build: {
    outDir: 'dist', // Capacitor webDir
  },
});
capacitor.config.ts:
typescript
import type { CapacitorConfig } from '@capacitor/cli';

const config: CapacitorConfig = {
  appId: 'com.company.app',
  appName: 'My App',
  webDir: 'dist',
};

export default config;
Add platforms and build:
bash
bun add @capacitor/ios @capacitor/android
bunx cap add ios
bunx cap add android
bun run build
bunx cap sync
创建新项目:
bash
bun create vite my-app --template react-ts
cd my-app
bun install
安装Capacitor:
bash
bun add @capacitor/core @capacitor/cli
bunx cap init
配置vite.config.ts:
typescript
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';

export default defineConfig({
  plugins: [react()],
  build: {
    outDir: 'dist', // Capacitor的webDir目录
  },
});
capacitor.config.ts:
typescript
import type { CapacitorConfig } from '@capacitor/cli';

const config: CapacitorConfig = {
  appId: 'com.company.app',
  appName: 'My App',
  webDir: 'dist',
};

export default config;
添加平台并构建:
bash
bun add @capacitor/ios @capacitor/android
bunx cap add ios
bunx cap add android
bun run build
bunx cap sync

Option 2: Create React App

方案2:Create React App

Create new project:
bash
bunx create-react-app my-app --template typescript
cd my-app
Install Capacitor:
bash
bun add @capacitor/core @capacitor/cli
bunx cap init
capacitor.config.ts:
typescript
const config: CapacitorConfig = {
  appId: 'com.company.app',
  appName: 'My App',
  webDir: 'build', // CRA outputs to build/
};
Build and sync:
bash
bun run build
bunx cap sync
创建新项目:
bash
bunx create-react-app my-app --template typescript
cd my-app
安装Capacitor:
bash
bun add @capacitor/core @capacitor/cli
bunx cap init
capacitor.config.ts:
typescript
const config: CapacitorConfig = {
  appId: 'com.company.app',
  appName: 'My App',
  webDir: 'build', // CRA的输出目录为build/
};
构建与同步:
bash
bun run build
bunx cap sync

React Router Configuration

React Router配置

Use HashRouter for mobile:
tsx
import { HashRouter as Router, Routes, Route } from 'react-router-dom';

function App() {
  return (
    <Router>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/about" element={<About />} />
      </Routes>
    </Router>
  );
}

移动端使用HashRouter:
tsx
import { HashRouter as Router, Routes, Route } from 'react-router-dom';

function App() {
  return (
    <Router>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/about" element={<About />} />
      </Routes>
    </Router>
  );
}

Vue + Capacitor

Vue + Capacitor

Vue works seamlessly with Capacitor.
Vue可与Capacitor无缝集成。

Create Vue + Capacitor Project

创建Vue + Capacitor项目

Using Vite:
bash
bun create vite my-app --template vue-ts
cd my-app
bun install
Install Capacitor:
bash
bun add @capacitor/core @capacitor/cli
bunx cap init
vite.config.ts:
typescript
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';

export default defineConfig({
  plugins: [vue()],
  build: {
    outDir: 'dist',
  },
});
capacitor.config.ts:
typescript
const config: CapacitorConfig = {
  appId: 'com.company.app',
  appName: 'My App',
  webDir: 'dist',
};
Add platforms:
bash
bun add @capacitor/ios @capacitor/android
bunx cap add ios
bunx cap add android
bun run build
bunx cap sync
使用Vite:
bash
bun create vite my-app --template vue-ts
cd my-app
bun install
安装Capacitor:
bash
bun add @capacitor/core @capacitor/cli
bunx cap init
vite.config.ts:
typescript
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';

export default defineConfig({
  plugins: [vue()],
  build: {
    outDir: 'dist',
  },
});
capacitor.config.ts:
typescript
const config: CapacitorConfig = {
  appId: 'com.company.app',
  appName: 'My App',
  webDir: 'dist',
};
添加平台:
bash
bun add @capacitor/ios @capacitor/android
bunx cap add ios
bunx cap add android
bun run build
bunx cap sync

Vue Router Configuration

Vue Router配置

Use hash mode for mobile:
typescript
// router/index.ts
import { createRouter, createWebHashHistory } from 'vue-router';

const router = createRouter({
  history: createWebHashHistory(),
  routes: [
    { path: '/', component: Home },
    { path: '/about', component: About },
  ],
});

export default router;

移动端使用哈希模式:
typescript
// router/index.ts
import { createRouter, createWebHashHistory } from 'vue-router';

const router = createRouter({
  history: createWebHashHistory(),
  routes: [
    { path: '/', component: Home },
    { path: '/about', component: About },
  ],
});

export default router;

Angular + Capacitor

Angular + Capacitor

Angular has excellent Capacitor integration.
Angular与Capacitor的集成非常完善。

Create Angular + Capacitor Project

创建Angular + Capacitor项目

Create Angular app:
bash
bunx @angular/cli new my-app
cd my-app
Install Capacitor:
bash
bun add @capacitor/core @capacitor/cli
bunx cap init
capacitor.config.ts:
typescript
const config: CapacitorConfig = {
  appId: 'com.company.app',
  appName: 'My App',
  webDir: 'dist/my-app/browser', // Angular 17+ output
};
For Angular 16 and below:
typescript
webDir: 'dist/my-app',
Add platforms:
bash
bun add @capacitor/ios @capacitor/android
bunx cap add ios
bunx cap add android
bun run build
bunx cap sync
创建Angular应用:
bash
bunx @angular/cli new my-app
cd my-app
安装Capacitor:
bash
bun add @capacitor/core @capacitor/cli
bunx cap init
capacitor.config.ts:
typescript
const config: CapacitorConfig = {
  appId: 'com.company.app',
  appName: 'My App',
  webDir: 'dist/my-app/browser', // Angular 17+的输出目录
};
适用于Angular 16及以下版本:
typescript
webDir: 'dist/my-app',
添加平台:
bash
bun add @capacitor/ios @capacitor/android
bunx cap add ios
bunx cap add android
bun run build
bunx cap sync

Angular Router Configuration

Angular Router配置

HashLocationStrategy for mobile:
typescript
// app.config.ts (Angular 17+)
import { provideRouter, withHashLocation } from '@angular/router';

export const appConfig: ApplicationConfig = {
  providers: [
    provideRouter(routes, withHashLocation()),
  ],
};
For Angular 16 and below:
typescript
// app.module.ts
import { LocationStrategy, HashLocationStrategy } from '@angular/common';

@NgModule({
  providers: [
    { provide: LocationStrategy, useClass: HashLocationStrategy }
  ],
})
export class AppModule {}

移动端使用HashLocationStrategy:
typescript
// app.config.ts(Angular 17+)
import { provideRouter, withHashLocation } from '@angular/router';

export const appConfig: ApplicationConfig = {
  providers: [
    provideRouter(routes, withHashLocation()),
  ],
};
适用于Angular 16及以下版本:
typescript
// app.module.ts
import { LocationStrategy, HashLocationStrategy } from '@angular/common';

@NgModule({
  providers: [
    { provide: LocationStrategy, useClass: HashLocationStrategy }
  ],
})
export class AppModule {}

Svelte + Capacitor

Svelte + Capacitor

Svelte and SvelteKit work great with Capacitor.
Svelte和SvelteKit可与Capacitor完美配合。

SvelteKit + Capacitor

SvelteKit + Capacitor

Create SvelteKit app:
bash
bunx create-svelte my-app
cd my-app
bun install
Install adapter-static:
bash
bun add -D @sveltejs/adapter-static
Configure svelte.config.js:
javascript
import adapter from '@sveltejs/adapter-static';

const config = {
  kit: {
    adapter: adapter({
      pages: 'build',
      assets: 'build',
      fallback: 'index.html',
    }),
  },
};

export default config;
Install Capacitor:
bash
bun add @capacitor/core @capacitor/cli
bunx cap init
capacitor.config.ts:
typescript
const config: CapacitorConfig = {
  appId: 'com.company.app',
  appName: 'My App',
  webDir: 'build',
};
Build and sync:
bash
bun run build
bunx cap sync
创建SvelteKit应用:
bash
bunx create-svelte my-app
cd my-app
bun install
安装adapter-static:
bash
bun add -D @sveltejs/adapter-static
配置svelte.config.js:
javascript
import adapter from '@sveltejs/adapter-static';

const config = {
  kit: {
    adapter: adapter({
      pages: 'build',
      assets: 'build',
      fallback: 'index.html',
    }),
  },
};

export default config;
安装Capacitor:
bash
bun add @capacitor/core @capacitor/cli
bunx cap init
capacitor.config.ts:
typescript
const config: CapacitorConfig = {
  appId: 'com.company.app',
  appName: 'My App',
  webDir: 'build',
};
构建与同步:
bash
bun run build
bunx cap sync

Vite + Svelte (Simpler Option)

Vite + Svelte(更简单的方案)

Create with Vite:
bash
bun create vite my-app --template svelte-ts
cd my-app
bun install
Install Capacitor:
bash
bun add @capacitor/core @capacitor/cli
bunx cap init
capacitor.config.ts:
typescript
const config: CapacitorConfig = {
  appId: 'com.company.app',
  appName: 'My App',
  webDir: 'dist',
};

使用Vite创建项目:
bash
bun create vite my-app --template svelte-ts
cd my-app
bun install
安装Capacitor:
bash
bun add @capacitor/core @capacitor/cli
bunx cap init
capacitor.config.ts:
typescript
const config: CapacitorConfig = {
  appId: 'com.company.app',
  appName: 'My App',
  webDir: 'dist',
};

Common Patterns Across Frameworks

各框架通用模式

1. Environment Detection

1. 环境检测

Detect if running in native app:
typescript
import { Capacitor } from '@capacitor/core';

const isNative = Capacitor.isNativePlatform();
const platform = Capacitor.getPlatform(); // 'ios', 'android', or 'web'

if (isNative) {
  // Use native plugins
} else {
  // Use web APIs
}
检测是否运行在原生应用中:
typescript
import { Capacitor } from '@capacitor/core';

const isNative = Capacitor.isNativePlatform();
const platform = Capacitor.getPlatform(); // 'ios', 'android' 或 'web'

if (isNative) {
  // 使用原生插件
} else {
  // 使用Web API
}

2. Deep Linking

2. 深度链接

Handle deep links in your app:
typescript
import { App } from '@capacitor/app';

App.addListener('appUrlOpen', (data) => {
  // Handle deep link
  const slug = data.url.split('.app').pop();
  // Navigate to route
});
在应用中处理深度链接:
typescript
import { App } from '@capacitor/app';

App.addListener('appUrlOpen', (data) => {
  // 处理深度链接
  const slug = data.url.split('.app').pop();
  // 导航到对应路由
});

3. Live Updates with Capgo

3. 使用Capgo实现实时更新

Add live updates to any framework:
bash
bun add @capgo/capacitor-updater
typescript
import { CapacitorUpdater } from '@capgo/capacitor-updater';

// Check for updates
const { id } = await CapacitorUpdater.download({
  url: 'https://api.capgo.app/updates',
});

// Apply update
await CapacitorUpdater.set({ id });
为任意框架添加实时更新功能:
bash
bun add @capgo/capacitor-updater
typescript
import { CapacitorUpdater } from '@capgo/capacitor-updater';

// 检查更新
const { id } = await CapacitorUpdater.download({
  url: 'https://api.capgo.app/updates',
});

// 应用更新
await CapacitorUpdater.set({ id });

4. Native UI Components

4. 原生UI组件

Use Ionic Framework for any framework:
bash
bun add @ionic/core
React:
bash
bun add @ionic/react @ionic/react-router
Vue:
bash
bun add @ionic/vue @ionic/vue-router
Angular:
bash
bun add @ionic/angular
为任意框架使用Ionic Framework:
bash
bun add @ionic/core
React:
bash
bun add @ionic/react @ionic/react-router
Vue:
bash
bun add @ionic/vue @ionic/vue-router
Angular:
bash
bun add @ionic/angular

5. Storage

5. 存储

Use Capacitor Preferences for all frameworks:
typescript
import { Preferences } from '@capacitor/preferences';

// Set value
await Preferences.set({ key: 'theme', value: 'dark' });

// Get value
const { value } = await Preferences.get({ key: 'theme' });

// Remove value
await Preferences.remove({ key: 'theme' });

// Clear all
await Preferences.clear();
所有框架均可使用Capacitor Preferences:
typescript
import { Preferences } from '@capacitor/preferences';

// 设置值
await Preferences.set({
  key: 'theme',
  value: 'dark',
});

// 获取值
const { value } = await Preferences.get({ key: 'theme' });

// 删除值
await Preferences.remove({ key: 'theme' });

// 清空所有数据
await Preferences.clear();

6. Camera Access

6. 相机访问

Same API across all frameworks:
typescript
import { Camera, CameraResultType } from '@capacitor/camera';

const photo = await Camera.getPhoto({
  quality: 90,
  allowEditing: true,
  resultType: CameraResultType.Uri,
});

const imageUrl = photo.webPath;

所有框架使用相同的API:
typescript
import { Camera, CameraResultType } from '@capacitor/camera';

const photo = await Camera.getPhoto({
  quality: 90,
  allowEditing: true,
  resultType: CameraResultType.Uri,
});

const imageUrl = photo.webPath;

Build Scripts for All Frameworks

适用于所有框架的构建脚本

Add these to package.json:
json
{
  "scripts": {
    "dev": "vite", // or next dev, ng serve, etc.
    "build": "vite build", // or next build, ng build, etc.
    "build:mobile": "vite build && cap sync",
    "ios": "cap run ios",
    "android": "cap run android",
    "sync": "cap sync"
  }
}

将以下脚本添加到package.json:
json
{
  "scripts": {
    "dev": "vite", // 或 next dev, ng serve等
    "build": "vite build", // 或 next build, ng build等
    "build:mobile": "vite build && cap sync",
    "ios": "cap run ios",
    "android": "cap run android",
    "sync": "cap sync"
  }
}

Routing Best Practices

路由最佳实践

Hash vs. History Mode

哈希模式 vs 历史模式

Hash mode (recommended for mobile):
  • Works without server configuration
  • URLs look like:
    #/about
  • No server-side routing needed
History mode (requires server):
  • Clean URLs:
    /about
  • Requires server fallback to index.html
  • Can have issues on mobile
Recommendation: Use hash mode for Capacitor apps.

哈希模式(推荐移动端使用):
  • 无需服务器配置即可工作
  • URL格式:
    #/about
  • 不需要服务端路由
历史模式(需要服务器支持):
  • URL更简洁:
    /about
  • 需要服务器配置回退到index.html
  • 在移动端可能出现问题
推荐方案:Capacitor应用使用哈希路由。

Common Issues and Solutions

常见问题与解决方案

Issue: Blank Screen on Mobile

问题:移动端出现空白屏幕

Cause: Incorrect
webDir
or build output.
Solution:
  1. Check build output directory matches
    webDir
    in capacitor.config.ts
  2. Rebuild:
    bun run build
  3. Sync:
    bunx cap sync
  4. Check browser console in device
原因
webDir
配置错误或构建产物路径不正确。
解决方案:
  1. 检查构建输出目录是否与capacitor.config.ts中的
    webDir
    一致
  2. 重新构建:
    bun run build
  3. 同步:
    bunx cap sync
  4. 检查设备的浏览器控制台

Issue: Routing Doesn't Work

问题:路由无法正常工作

Cause: Using history mode without proper configuration.
Solution: Switch to hash routing:
  • React:
    HashRouter
  • Vue:
    createWebHashHistory()
  • Angular:
    HashLocationStrategy
  • SvelteKit: Configure fallback
原因:使用历史模式但未正确配置。
解决方案: 切换为哈希路由:
  • React:使用
    HashRouter
  • Vue:使用
    createWebHashHistory()
  • Angular:使用
    HashLocationStrategy
  • SvelteKit:配置fallback

Issue: Environment Variables Not Working

问题:环境变量不生效

Cause: Build-time variables not being replaced.
Solution: Use framework-specific env variable patterns:
  • Next.js:
    NEXT_PUBLIC_
  • Vite:
    VITE_
  • Create React App:
    REACT_APP_
  • Angular:
    environment.ts
原因:构建时变量未被替换。
解决方案: 使用框架特定的环境变量命名规则:
  • Next.js:
    NEXT_PUBLIC_
    前缀
  • Vite:
    VITE_
    前缀
  • Create React App:
    REACT_APP_
    前缀
  • Angular:使用
    environment.ts

Issue: API Calls Fail on Device

问题:设备上API调用失败

Cause: CORS or localhost URLs.
Solution:
  1. Use production API URLs
  2. Configure CORS on backend
  3. Use Capacitor HTTP plugin for native requests:
typescript
import { CapacitorHttp } from '@capacitor/core';

const response = await CapacitorHttp.get({
  url: 'https://api.example.com/data',
});

原因:CORS问题或使用localhost地址。
解决方案:
  1. 使用生产环境API地址
  2. 在后端配置CORS
  3. 使用Capacitor HTTP插件发起原生请求:
typescript
import { CapacitorHttp } from '@capacitor/core';

const response = await CapacitorHttp.get({
  url: 'https://api.example.com/data',
});

Framework-Specific Plugins

框架专属插件

Ionic Framework provides native UI components:
  • @ionic/react - React components
  • @ionic/vue - Vue components
  • @ionic/angular - Angular components
Konsta UI for Tailwind CSS:
  • Works with React, Vue, Svelte
  • iOS and Material Design themes
See
ionic-design
and
konsta-ui
skills for details.

Ionic Framework提供原生UI组件:
  • @ionic/react - React组件库
  • @ionic/vue - Vue组件库
  • @ionic/angular - Angular组件库
适用于Tailwind CSS的Konsta UI:
  • 支持React、Vue、Svelte
  • 提供iOS和Material Design主题
详情请参考
ionic-design
konsta-ui
相关指南。

Deployment Checklist

部署检查清单

  • Configure static export (Next.js:
    output: 'export'
    )
  • Set correct
    webDir
    in capacitor.config.ts
  • Use hash routing for mobile
  • Disable image optimization (Next.js)
  • Remove SSR/API routes dependencies
  • Add native permissions (Info.plist, AndroidManifest.xml)
  • Test on physical devices
  • Configure splash screen and icons
  • Set up live updates with Capgo (optional)
  • Build and test on iOS and Android

  • 配置静态导出(Next.js:
    output: 'export'
  • 在capacitor.config.ts中设置正确的
    webDir
  • 移动端使用哈希路由
  • 禁用图片优化(Next.js)
  • 移除对SSR/API路由的依赖
  • 添加原生权限(Info.plist、AndroidManifest.xml)
  • 在物理设备上测试
  • 配置启动画面和图标
  • (可选)使用Capgo设置实时更新
  • 在iOS和Android平台上构建并测试

Resources

资源

Framework-Specific Guides

框架专属指南

For detailed guides on specific frameworks:

如需特定框架的详细指南:

Next Steps

后续步骤

  1. Choose your framework and follow the setup above
  2. Configure static export/build
  3. Install and configure Capacitor
  4. Add platforms (iOS/Android)
  5. Build and sync
  6. Test on devices
  7. Add native features with plugins
  8. Set up live updates with Capgo
  1. 选择你的框架并按照上述步骤设置
  2. 配置静态导出/构建
  3. 安装并配置Capacitor
  4. 添加平台(iOS/Android)
  5. 构建并同步
  6. 在设备上测试
  7. 使用插件添加原生功能
  8. 使用Capgo设置实时更新