framework-to-capacitor
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseFramework 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
框架支持矩阵
| Framework | Static Export | SSR Support | Recommended Approach |
|---|---|---|---|
| Next.js | ✅ Yes | ❌ No | Static export (output: 'export') |
| React | ✅ Yes | N/A | Create React App or Vite |
| Vue | ✅ Yes | ❌ No | Vite or Vue CLI |
| Angular | ✅ Yes | ❌ No | Angular CLI |
| Svelte | ✅ Yes | ❌ No | SvelteKit with adapter-static |
| Remix | ✅ Yes | ❌ No | SPA mode |
| Solid | ✅ Yes | ❌ No | Vite |
| Qwik | ✅ Yes | ❌ No | Static 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 buildThis creates an directory with static files.
out/bash
bun run build此命令会创建包含静态文件的目录。
out/Step 3: Install Capacitor
步骤3:安装Capacitor
bash
bun add @capacitor/core @capacitor/cli
bunx cap initConfiguration:
- App name: Your app name
- App ID: com.company.app
- Web directory: (Next.js static export output)
out
bash
bun add @capacitor/core @capacitor/cli
bunx cap init配置项:
- App name:你的应用名称
- App ID:com.company.app
- Web directory:(Next.js静态导出的输出目录)
out
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 androidbash
bun add @capacitor/ios @capacitor/android
bunx cap add ios
bunx cap add androidStep 6: Build and Sync
步骤6:构建与同步
bash
undefinedbash
undefinedBuild Next.js
构建Next.js应用
bun run build
bun run build
Sync with native projects
与原生项目同步
bunx cap sync
undefinedbunx cap sync
undefinedStep 7: Run on Device
步骤7:在设备上运行
iOS:
bash
bunx cap open iosiOS:
bash
bunx cap open iosBuild and run in Xcode
在Xcode中构建并运行
**Android:**
```bash
bunx cap open android
**Android:**
```bash
bunx cap open androidBuild and run in Android Studio
在Android Studio中构建并运行
undefinedundefinedNext.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: trueNext.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:
- External API: Call a separate backend
- Capacitor plugins: Use native features
- 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路由在静态导出中无法工作,可使用以下替代方案:
- 外部API:调用独立的后端服务
- Capacitor插件:使用原生功能
- 本地存储:使用
@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 installInstall Capacitor:
bash
bun add @capacitor/core @capacitor/cli
bunx cap initConfigure 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 syncOption 2: Create React App
方案2:Create React App
Create new project:
bash
bunx create-react-app my-app --template typescript
cd my-appInstall Capacitor:
bash
bun add @capacitor/core @capacitor/cli
bunx cap initcapacitor.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 initcapacitor.config.ts:
typescript
const config: CapacitorConfig = {
appId: 'com.company.app',
appName: 'My App',
webDir: 'build', // CRA的输出目录为build/
};构建与同步:
bash
bun run build
bunx cap syncReact 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 installInstall Capacitor:
bash
bun add @capacitor/core @capacitor/cli
bunx cap initvite.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 initvite.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 syncVue 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-appInstall Capacitor:
bash
bun add @capacitor/core @capacitor/cli
bunx cap initcapacitor.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 initcapacitor.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 syncAngular 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 installInstall adapter-static:
bash
bun add -D @sveltejs/adapter-staticConfigure 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 initcapacitor.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 initcapacitor.config.ts:
typescript
const config: CapacitorConfig = {
appId: 'com.company.app',
appName: 'My App',
webDir: 'build',
};构建与同步:
bash
bun run build
bunx cap syncVite + Svelte (Simpler Option)
Vite + Svelte(更简单的方案)
Create with Vite:
bash
bun create vite my-app --template svelte-ts
cd my-app
bun installInstall Capacitor:
bash
bun add @capacitor/core @capacitor/cli
bunx cap initcapacitor.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 initcapacitor.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-updatertypescript
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-updatertypescript
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/coreReact:
bash
bun add @ionic/react @ionic/react-routerVue:
bash
bun add @ionic/vue @ionic/vue-routerAngular:
bash
bun add @ionic/angular为任意框架使用Ionic Framework:
bash
bun add @ionic/coreReact:
bash
bun add @ionic/react @ionic/react-routerVue:
bash
bun add @ionic/vue @ionic/vue-routerAngular:
bash
bun add @ionic/angular5. 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 or build output.
webDirSolution:
- Check build output directory matches in capacitor.config.ts
webDir - Rebuild:
bun run build - Sync:
bunx cap sync - Check browser console in device
原因:配置错误或构建产物路径不正确。
webDir解决方案:
- 检查构建输出目录是否与capacitor.config.ts中的一致
webDir - 重新构建:
bun run build - 同步:
bunx cap sync - 检查设备的浏览器控制台
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:
- Use production API URLs
- Configure CORS on backend
- 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地址。
解决方案:
- 使用生产环境API地址
- 在后端配置CORS
- 使用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 and skills for details.
ionic-designkonsta-uiIonic Framework提供原生UI组件:
- @ionic/react - React组件库
- @ionic/vue - Vue组件库
- @ionic/angular - Angular组件库
适用于Tailwind CSS的Konsta UI:
- 支持React、Vue、Svelte
- 提供iOS和Material Design主题
详情请参考和相关指南。
ionic-designkonsta-uiDeployment Checklist
部署检查清单
- Configure static export (Next.js: )
output: 'export' - Set correct in capacitor.config.ts
webDir - 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
资源
- Capacitor Docs: https://capacitorjs.com/docs
- Next.js Static Export: https://nextjs.org/docs/app/building-your-application/deploying/static-exports
- Ionic Framework: https://ionicframework.com
- Capgo Blog: https://capgo.app/blog
- Community Forum: https://forum.ionicframework.com
- Capacitor官方文档:https://capacitorjs.com/docs
- Next.js静态导出:https://nextjs.org/docs/app/building-your-application/deploying/static-exports
- Ionic Framework:https://ionicframework.com
- Capgo博客:https://capgo.app/blog
- 社区论坛:https://forum.ionicframework.com
Framework-Specific Guides
框架专属指南
For detailed guides on specific frameworks:
- Next.js + Capacitor: https://capgo.app/blog/how-to-use-capacitor-with-nextjs
- Ionic Framework: See skill
ionic-design - Konsta UI: See skill
konsta-ui
如需特定框架的详细指南:
- Next.js + Capacitor:https://capgo.app/blog/how-to-use-capacitor-with-nextjs
- Ionic Framework:参考指南
ionic-design - Konsta UI:参考指南
konsta-ui
Next Steps
后续步骤
- Choose your framework and follow the setup above
- Configure static export/build
- Install and configure Capacitor
- Add platforms (iOS/Android)
- Build and sync
- Test on devices
- Add native features with plugins
- Set up live updates with Capgo
- 选择你的框架并按照上述步骤设置
- 配置静态导出/构建
- 安装并配置Capacitor
- 添加平台(iOS/Android)
- 构建并同步
- 在设备上测试
- 使用插件添加原生功能
- 使用Capgo设置实时更新