重要前提
安装AI Skills的关键前提是:必须科学上网,且开启TUN模式,这一点至关重要,直接决定安装能否顺利完成,在此郑重提醒三遍:科学上网,科学上网,科学上网。查看完整安装教程 →
framework-to-capacitor by cap-go/capgo-skills
npx skills add https://github.com/cap-go/capgo-skills --skill framework-to-capacitor将 Web 框架与 Capacitor 集成以构建移动应用的全面指南。
| 框架 | 静态导出 | SSR 支持 | 推荐方法 |
|---|---|---|---|
| Next.js | ✅ 支持 | ❌ 不支持 | 静态导出 (output: 'export') |
| React | ✅ 支持 | N/A | Create React App 或 Vite |
| Vue | ✅ 支持 | ❌ 不支持 | Vite 或 Vue CLI |
| Angular | ✅ 支持 | ❌ 不支持 | Angular CLI |
| Svelte | ✅ 支持 |
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
| ❌ 不支持 |
| 带 adapter-static 的 SvelteKit |
| Remix | ✅ 支持 | ❌ 不支持 | SPA 模式 |
| Solid | ✅ 支持 | ❌ 不支持 | Vite |
| Qwik | ✅ 支持 | ❌ 不支持 | 静态站点模式 |
关键提示:Capacitor 需要静态的 HTML/CSS/JS 文件。SSR(服务端渲染)在原生应用中无法工作。
Next.js 在 React 应用中非常流行。Capacitor 要求进行静态导出。
适用于 Next.js 13+(App 路由):
// next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
output: 'export',
images: {
unoptimized: true, // 静态导出所必需
},
trailingSlash: true, // 有助于移动端路由
};
module.exports = nextConfig;
适用于 Next.js 12(Pages 路由):
// next.config.js
module.exports = {
output: 'export',
images: {
unoptimized: true,
},
trailingSlash: true,
};
bun run build
这将创建一个包含静态文件的 out/ 目录。
bun add @capacitor/core @capacitor/cli
bunx cap init
配置:
out(Next.js 静态导出输出目录)创建 capacitor.config.ts:
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;
bun add @capacitor/ios @capacitor/android
bunx cap add ios
bunx cap add android
# 构建 Next.js
bun run build
# 与原生项目同步
bunx cap sync
iOS:
bunx cap open ios
# 在 Xcode 中构建并运行
Android:
bunx cap open android
# 在 Android Studio 中构建并运行
对于复杂应用使用哈希路由:
// next.config.js
const nextConfig = {
output: 'export',
basePath: '',
assetPrefix: '',
};
module.exports = nextConfig;
或者使用 Next.js 内置的路由(与 trailingSlash: true 配合使用)。
next/image 无法与静态导出一起工作。请使用替代方案:
方案 1:使用标准 img 标签
// 替代 next/image
<img src="/images/photo.jpg" alt="Photo" />
方案 2:使用自定义 Image 组件
// 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} />;
};
API 路由在静态导出中无法工作。 请使用替代方案:
@capacitor/preferencesimport { 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 || '{}');
中间件在静态导出中无法工作。 请在客户端处理逻辑:
// 在你的 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>Protected content</div>;
}
package.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 使用 Vite 或 Create React App 与 Capacitor 配合良好。
创建新项目:
bun create vite my-app --template react-ts
cd my-app
bun install
安装 Capacitor:
bun add @capacitor/core @capacitor/cli
bunx cap init
配置 vite.config.ts:
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
export default defineConfig({
plugins: [react()],
build: {
outDir: 'dist', // Capacitor webDir
},
});
capacitor.config.ts:
import type { CapacitorConfig } from '@capacitor/cli';
const config: CapacitorConfig = {
appId: 'com.company.app',
appName: 'My App',
webDir: 'dist',
};
export default config;
添加平台并构建:
bun add @capacitor/ios @capacitor/android
bunx cap add ios
bunx cap add android
bun run build
bunx cap sync
创建新项目:
bunx create-react-app my-app --template typescript
cd my-app
安装 Capacitor:
bun add @capacitor/core @capacitor/cli
bunx cap init
capacitor.config.ts:
const config: CapacitorConfig = {
appId: 'com.company.app',
appName: 'My App',
webDir: 'build', // CRA 输出到 build/
};
构建与同步:
bun run build
bunx cap sync
为移动端使用 HashRouter:
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 无缝协作。
使用 Vite:
bun create vite my-app --template vue-ts
cd my-app
bun install
安装 Capacitor:
bun add @capacitor/core @capacitor/cli
bunx cap init
vite.config.ts:
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
export default defineConfig({
plugins: [vue()],
build: {
outDir: 'dist',
},
});
capacitor.config.ts:
const config: CapacitorConfig = {
appId: 'com.company.app',
appName: 'My App',
webDir: 'dist',
};
添加平台:
bun add @capacitor/ios @capacitor/android
bunx cap add ios
bunx cap add android
bun run build
bunx cap sync
为移动端使用哈希模式:
// 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 应用:
bunx @angular/cli new my-app
cd my-app
安装 Capacitor:
bun add @capacitor/core @capacitor/cli
bunx cap init
capacitor.config.ts:
const config: CapacitorConfig = {
appId: 'com.company.app',
appName: 'My App',
webDir: 'dist/my-app/browser', // Angular 17+ 输出目录
};
对于 Angular 16 及以下版本:
webDir: 'dist/my-app',
添加平台:
bun add @capacitor/ios @capacitor/android
bunx cap add ios
bunx cap add android
bun run build
bunx cap sync
为移动端使用 HashLocationStrategy:
// app.config.ts (Angular 17+)
import { provideRouter, withHashLocation } from '@angular/router';
export const appConfig: ApplicationConfig = {
providers: [
provideRouter(routes, withHashLocation()),
],
};
对于 Angular 16 及以下版本:
// app.module.ts
import { LocationStrategy, HashLocationStrategy } from '@angular/common';
@NgModule({
providers: [
{ provide: LocationStrategy, useClass: HashLocationStrategy }
],
})
export class AppModule {}
Svelte 和 SvelteKit 与 Capacitor 配合良好。
创建 SvelteKit 应用:
bunx create-svelte my-app
cd my-app
bun install
安装 adapter-static:
bun add -D @sveltejs/adapter-static
配置 svelte.config.js:
import adapter from '@sveltejs/adapter-static';
const config = {
kit: {
adapter: adapter({
pages: 'build',
assets: 'build',
fallback: 'index.html',
}),
},
};
export default config;
安装 Capacitor:
bun add @capacitor/core @capacitor/cli
bunx cap init
capacitor.config.ts:
const config: CapacitorConfig = {
appId: 'com.company.app',
appName: 'My App',
webDir: 'build',
};
构建与同步:
bun run build
bunx cap sync
使用 Vite 创建:
bun create vite my-app --template svelte-ts
cd my-app
bun install
安装 Capacitor:
bun add @capacitor/core @capacitor/cli
bunx cap init
capacitor.config.ts:
const config: CapacitorConfig = {
appId: 'com.company.app',
appName: 'My App',
webDir: 'dist',
};
检测是否在原生应用中运行:
import { Capacitor } from '@capacitor/core';
const isNative = Capacitor.isNativePlatform();
const platform = Capacitor.getPlatform(); // 'ios', 'android', 或 'web'
if (isNative) {
// 使用原生插件
} else {
// 使用 Web API
}
在你的应用中处理深度链接:
import { App } from '@capacitor/app';
App.addListener('appUrlOpen', (data) => {
// 处理深度链接
const slug = data.url.split('.app').pop();
// 导航到路由
});
为任何框架添加实时更新:
bun add @capgo/capacitor-updater
import { CapacitorUpdater } from '@capgo/capacitor-updater';
// 检查更新
const { id } = await CapacitorUpdater.download({
url: 'https://api.capgo.app/updates',
});
// 应用更新
await CapacitorUpdater.set({ id });
为任何框架使用 Ionic Framework:
bun add @ionic/core
React:
bun add @ionic/react @ionic/react-router
Vue:
bun add @ionic/vue @ionic/vue-router
Angular:
bun add @ionic/angular
为所有框架使用 Capacitor Preferences:
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();
所有框架使用相同的 API:
import { Camera, CameraResultType } from '@capacitor/camera';
const photo = await Camera.getPhoto({
quality: 90,
allowEditing: true,
resultType: CameraResultType.Uri,
});
const imageUrl = photo.webPath;
将这些添加到 package.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"
}
}
哈希模式(推荐用于移动端):
#/about历史模式(需要服务器):
/about建议:为 Capacitor 应用使用哈希模式。
原因:webDir 或构建输出目录不正确。
解决方案:
webDir 匹配bun run buildbunx cap sync原因:使用了历史模式但没有正确配置。
解决方案: 切换到哈希路由:
HashRoutercreateWebHashHistory()HashLocationStrategy原因:构建时变量未被替换。
解决方案: 使用框架特定的环境变量模式:
NEXT_PUBLIC_VITE_REACT_APP_environment.ts原因:CORS 或 localhost URL。
解决方案:
import { CapacitorHttp } from '@capacitor/core';
const response = await CapacitorHttp.get({
url: 'https://api.example.com/data',
});
Ionic Framework 提供原生 UI 组件:
用于 Tailwind CSS 的 Konsta UI:
详情请参阅 ionic-design 和 konsta-ui 技能。
output: 'export')webDir关于特定框架的详细指南:
ionic-design 技能konsta-ui 技能每周安装次数
42
代码仓库
GitHub 星标数
18
首次出现
2026年2月13日
安全审计
已安装于
gemini-cli42
codex41
opencode41
github-copilot40
amp39
kimi-cli39
Comprehensive guide for integrating web frameworks with Capacitor to build mobile apps.
| 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.
Next.js is popular for React apps. Capacitor requires static export.
For Next.js 13+ (App Router):
// 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):
// next.config.js
module.exports = {
output: 'export',
images: {
unoptimized: true,
},
trailingSlash: true,
};
bun run build
This creates an out/ directory with static files.
bun add @capacitor/core @capacitor/cli
bunx cap init
Configuration:
out (Next.js static export output)Create capacitor.config.ts:
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;
bun add @capacitor/ios @capacitor/android
bunx cap add ios
bunx cap add android
# Build Next.js
bun run build
# Sync with native projects
bunx cap sync
iOS:
bunx cap open ios
# Build and run in Xcode
Android:
bunx cap open android
# Build and run in Android Studio
Use hash routing for complex apps:
// next.config.js
const nextConfig = {
output: 'export',
basePath: '',
assetPrefix: '',
};
Or use Next.js's built-in routing (works with trailingSlash: true).
next/image doesn't work with static export. Use alternatives:
Option 1: Use standard img tag
// Instead of next/image
<img src="/images/photo.jpg" alt="Photo" />
Option 2: Use a custom Image component
// 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} />;
};
API routes don't work in static export. Use alternatives:
@capacitor/preferencesimport { 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 || '{}');
Middleware doesn't work in static export. Handle logic client-side:
// 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>;
}
package.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 works great with Capacitor using Vite or Create React App.
Create new project:
bun create vite my-app --template react-ts
cd my-app
bun install
Install Capacitor:
bun add @capacitor/core @capacitor/cli
bunx cap init
Configure vite.config.ts:
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
export default defineConfig({
plugins: [react()],
build: {
outDir: 'dist', // Capacitor webDir
},
});
capacitor.config.ts:
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:
bun add @capacitor/ios @capacitor/android
bunx cap add ios
bunx cap add android
bun run build
bunx cap sync
Create new project:
bunx create-react-app my-app --template typescript
cd my-app
Install Capacitor:
bun add @capacitor/core @capacitor/cli
bunx cap init
capacitor.config.ts:
const config: CapacitorConfig = {
appId: 'com.company.app',
appName: 'My App',
webDir: 'build', // CRA outputs to build/
};
Build and sync:
bun run build
bunx cap sync
Use HashRouter for mobile:
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 works seamlessly with Capacitor.
Using Vite:
bun create vite my-app --template vue-ts
cd my-app
bun install
Install Capacitor:
bun add @capacitor/core @capacitor/cli
bunx cap init
vite.config.ts:
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
export default defineConfig({
plugins: [vue()],
build: {
outDir: 'dist',
},
});
capacitor.config.ts:
const config: CapacitorConfig = {
appId: 'com.company.app',
appName: 'My App',
webDir: 'dist',
};
Add platforms:
bun add @capacitor/ios @capacitor/android
bunx cap add ios
bunx cap add android
bun run build
bunx cap sync
Use hash mode for mobile:
// 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 has excellent Capacitor integration.
Create Angular app:
bunx @angular/cli new my-app
cd my-app
Install Capacitor:
bun add @capacitor/core @capacitor/cli
bunx cap init
capacitor.config.ts:
const config: CapacitorConfig = {
appId: 'com.company.app',
appName: 'My App',
webDir: 'dist/my-app/browser', // Angular 17+ output
};
For Angular 16 and below:
webDir: 'dist/my-app',
Add platforms:
bun add @capacitor/ios @capacitor/android
bunx cap add ios
bunx cap add android
bun run build
bunx cap sync
HashLocationStrategy for mobile:
// app.config.ts (Angular 17+)
import { provideRouter, withHashLocation } from '@angular/router';
export const appConfig: ApplicationConfig = {
providers: [
provideRouter(routes, withHashLocation()),
],
};
For Angular 16 and below:
// app.module.ts
import { LocationStrategy, HashLocationStrategy } from '@angular/common';
@NgModule({
providers: [
{ provide: LocationStrategy, useClass: HashLocationStrategy }
],
})
export class AppModule {}
Svelte and SvelteKit work great with Capacitor.
Create SvelteKit app:
bunx create-svelte my-app
cd my-app
bun install
Install adapter-static:
bun add -D @sveltejs/adapter-static
Configure svelte.config.js:
import adapter from '@sveltejs/adapter-static';
const config = {
kit: {
adapter: adapter({
pages: 'build',
assets: 'build',
fallback: 'index.html',
}),
},
};
export default config;
Install Capacitor:
bun add @capacitor/core @capacitor/cli
bunx cap init
capacitor.config.ts:
const config: CapacitorConfig = {
appId: 'com.company.app',
appName: 'My App',
webDir: 'build',
};
Build and sync:
bun run build
bunx cap sync
Create with Vite:
bun create vite my-app --template svelte-ts
cd my-app
bun install
Install Capacitor:
bun add @capacitor/core @capacitor/cli
bunx cap init
capacitor.config.ts:
const config: CapacitorConfig = {
appId: 'com.company.app',
appName: 'My App',
webDir: 'dist',
};
Detect if running in native app:
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
}
Handle deep links in your app:
import { App } from '@capacitor/app';
App.addListener('appUrlOpen', (data) => {
// Handle deep link
const slug = data.url.split('.app').pop();
// Navigate to route
});
Add live updates to any framework:
bun add @capgo/capacitor-updater
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 });
Use Ionic Framework for any framework:
bun add @ionic/core
React:
bun add @ionic/react @ionic/react-router
Vue:
bun add @ionic/vue @ionic/vue-router
Angular:
bun add @ionic/angular
Use Capacitor Preferences for all frameworks:
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();
Same API across all frameworks:
import { Camera, CameraResultType } from '@capacitor/camera';
const photo = await Camera.getPhoto({
quality: 90,
allowEditing: true,
resultType: CameraResultType.Uri,
});
const imageUrl = photo.webPath;
Add these to package.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"
}
}
Hash mode (recommended for mobile):
#/aboutHistory mode (requires server):
/aboutRecommendation : Use hash mode for Capacitor apps.
Cause : Incorrect webDir or build output.
Solution:
webDir in capacitor.config.tsbun run buildbunx cap syncCause : Using history mode without proper configuration.
Solution: Switch to hash routing:
HashRoutercreateWebHashHistory()HashLocationStrategyCause : Build-time variables not being replaced.
Solution: Use framework-specific env variable patterns:
NEXT_PUBLIC_VITE_REACT_APP_environment.tsCause : CORS or localhost URLs.
Solution:
import { CapacitorHttp } from '@capacitor/core';
const response = await CapacitorHttp.get({
url: 'https://api.example.com/data',
});
Ionic Framework provides native UI components:
Konsta UI for Tailwind CSS:
See ionic-design and konsta-ui skills for details.
output: 'export')webDir in capacitor.config.tsFor detailed guides on specific frameworks:
ionic-design skillkonsta-ui skillWeekly Installs
42
Repository
GitHub Stars
18
First Seen
Feb 13, 2026
Security Audits
Gen Agent Trust HubPassSocketPassSnykPass
Installed on
gemini-cli42
codex41
opencode41
github-copilot40
amp39
kimi-cli39
2025 Node.js 最佳实践指南:框架选择、架构原则与错误处理
5,500 周安装
小红书数据分析平台 Xinhong Data:账户增长、内容表现、达人合作、行业趋势深度洞察
62 周安装
KeyID Agent Kit MCP:为AI代理提供免费电子邮件地址和27种工具
570 周安装
Medusa 管理员用户创建指南:使用 new-user Skill 快速配置后台账户
562 周安装
数据分析验证工具 - 分享前审查分析准确性、方法论和潜在偏见
581 周安装
UI/UX设计师专家技能:精通设计系统、无障碍设计与现代工作流程
569 周安装
Grimmory 自托管图书馆管理器:支持 EPUB/PDF/MOBI/CBZ 的 Docker 部署方案
588 周安装